home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / win_utl2 / pspa370a.zip / POM.DOC < prev    next >
Text File  |  1996-04-26  |  287KB  |  6,747 lines

  1.  
  2.     ===========================================================================
  3.     ===========================================================================
  4.     ============================                   ============================
  5.     ============================                   ============================
  6.     ============================   PARSE-O-MATIC   ============================
  7.     ============================                   ============================
  8.     ============================                   ============================
  9.     ===========================================================================
  10.     ===========================================================================
  11.               
  12.  
  13.  
  14.               Copyright (C) 1986, 1996 by Pinnacle Software (Montreal)
  15.  
  16.  
  17.               
  18.     +------------------------ MULTI-PLATFORM SUPPORT -------------------------+
  19.     |                                                                         |
  20.     |                                                                         |
  21.     |          Runs under MS-DOS, Windows (including Win95) and OS/2          |
  22.     |                                                                         |
  23.     |                                                                         |
  24.     +------- HERE ARE A FEW OF THE THINGS PARSE-O-MATIC CAN DO FOR YOU -------+
  25.     |                                                                         |
  26.     |                                                                         |
  27.     |      Importing             Exporting             Automated Editing      |
  28.     |      Text Extraction       Data Conversion       Table Lookup           |
  29.     |      Retabulation          Info Weeding          Selective Copying      |
  30.     |      Binary-File to Text   Report Reformatting   Wide-Text Folding      |
  31.     |      Auto-Batch Creation   Comm-log Trimming     Tab Replacement        |
  32.     |      Character Filtering   Column Switching      DBF Interpretation     |
  33.     |      De-uppercasing        Name Properization    And much more!         |
  34.     |                                                                         |
  35.     |                                                                         |
  36.     +---- INPUT AND OUTPUT METHODS CURRENTLY SUPPORTED BY PARSE-O-MATIC ------+
  37.     |                                                                         |
  38.     |                                                                         |
  39.     |   Input:  Text (any format), Binary, DBF (DBase), Fixed-Record-Length,  |
  40.     |           Variable-Record-Length, EBCDIC                                |
  41.     |                                                                         |
  42.     |  Output:  Text (e.g. flat, comma-delimited, paginated, hex), Binary,    |
  43.     |           Fixed-Record-Length, Variable-Record-Length, EBCDIC,          |
  44.     |           Generic output devices (e.g. COM1: or LPT2:)                  |
  45.     |                                                                         |
  46.     |                                                                         |
  47.     +-------------------------------------------------------------------------+
  48.  
  49.  
  50.  
  51.     +------------------------ WHO USES PARSE-O-MATIC? ------------------------+
  52.     |                                                                         |
  53.     |                                                                         |
  54.     |                     Our corporate customers include:                    |
  55.     |                                                                         |
  56.     |     Boeing, CompUSA, Dresdner Bank, Eaton, Eddy, First Federal Bank,    |
  57.     |    Georgia Gulf, Harris Semiconductor, Home Box Office (HBO), Hughes,   |
  58.     |    McCain Foods, McDonald's, Nestle, Nike, Pacific Gas and Electric,    |
  59.     |      Philip Morris, Pitney Bowes, Prentice Hall, Procter & Gamble,      |
  60.     |        Royal Bank, Royal Caribbean, Sun Life, Visa International        |
  61.     |                                                                         |
  62.     |                                                                         |
  63.     +----------------------- UNSOLICITED TESTIMONIALS ------------------------+
  64.     |                                                                         |
  65.     |                                                                         |
  66.     |   "Parse-O-Matic is absolutely great.  I use it when I collect data     |
  67.     |   from the McDonald's restaurants in Switzerland.  POM has paid for     |
  68.     |   itself so many times ..." -- Chris Friedli                            |
  69.     |                                                                         |
  70.     |                                                                         |
  71.     |   "Parse-O-Matic is a wonderful time saver .... Each report that I      |
  72.     |   can convert from our ... accounting system saves our company about    |
  73.     |   500 man hours per year." -- R. Brooker                                |
  74.     |                                                                         |
  75.     |                                                                         |
  76.     |   "In 30 years of working with computers, this is by far the easiest    |
  77.     |   way I have found to extract data from files.  I was very surprised    |
  78.     |   that the program just took a few seconds to chew its way through      |
  79.     |   1MB of data.  You ought to mention it's FAST." -- Koenraad Rutgers    |
  80.     |                                                                         |
  81.     +-------------------------------------------------------------------------+
  82.  
  83.  
  84.  
  85.     ===========================================================================
  86.                              AN OVERVIEW OF THIS MANUAL
  87.     ===========================================================================
  88.  
  89.  
  90.     Introduction . . . . . . . . What is Parse-O-Matic?
  91.                                  Parse-O-Matic Versus Automatic Converters
  92.                                  Why You Need Parse-O-Matic -- An Example
  93.                                  Parse-O-Matic to the Rescue!
  94.                                  How it Works
  95.                                  How to Contact Us
  96.  
  97.  
  98.     Fundamentals . . . . . . . . The Parse-O-Matic Command
  99.                                  The POM File
  100.                                  Padding for Clarity
  101.                                  A Simple Example
  102.  
  103.  
  104.     Quick Reference  . . . . . . Command Descriptions
  105.                                  Command Formats
  106.  
  107.  
  108.     Basic Commands . . . . . . . Set, If
  109.  
  110.  
  111.     Output Commands  . . . . . . OFile, Out, OutEnd, OutHdg, OutPage, PageLen
  112.  
  113.  
  114.     Input Commands . . . . . . . The Get Command
  115.                                    Variable Length Records
  116.                                    Delimiter-Terminated Data
  117.                                    Handling Long Strings
  118.                                  The GetText Command
  119.                                  The ReadNext Command
  120.                                    End of File Conditions
  121.                                    Optional Comparisons
  122.                                    Ignoring Null Lines
  123.                                    Saving the Previous Line
  124.  
  125.  
  126.     Input Filters  . . . . . . . Minlen, Ignore, Accept
  127.  
  128.  
  129.     Flow Control Commands  . . . Begin, Else, End, Again, Done, NextFile,
  130.                                  Halt, Prologue, Epilogue
  131.  
  132.  
  133.     Variable Modifiers . . . . . The Trim Command
  134.                                  The Pad Command
  135.                                  The Change Command
  136.                                  The CvtCase Command
  137.                                    Control Settings
  138.                                  The Proper Command
  139.                                  The Insert Command
  140.                                  The Append Command
  141.                                  The MapFile Command
  142.                                    What is a Map File?
  143.                                    Sample Map Files
  144.                                    Map File Format
  145.                                    Search Order
  146.                                    Case Matching
  147.                                    Reverse Mapping
  148.                                    Irreversible Mapping
  149.                                    Memory Limitations
  150.                                    An Example of Remapping
  151.                                  The Remap Command
  152.                                    Remap Versus Change
  153.                                    Using Remap
  154.  
  155.  
  156.     Free-Form Commands . . . . . What are Free-Form Commands?
  157.                                  The Parse Command
  158.                                    Decapsulators
  159.                                    Sample Application
  160.                                    The Occurence Number
  161.                                    Finding the Last Occurence
  162.                                    Unsuccessful Searches
  163.                                    The Control Setting
  164.                                    The Plain Decapsulator
  165.                                    The Null Decapsulator
  166.                                    Null Decapsulators Versus Exclusion
  167.                                    Overlapping Decapsulators
  168.                                    Parsing Empty Fields
  169.                                    Additional Examples
  170.                                  The Peel Command
  171.                                    The Control Setting
  172.                                    Parsing Empty Fields
  173.                                    The Left-Peeling Method
  174.  
  175.  
  176.     Positional Commands  . . . . General Discussion
  177.                                    What are Positional Commands?
  178.                                    Why Use Positional Commands?
  179.                                    A Cautionary Note
  180.                                  The SetLen Command
  181.                                  The Delete Command
  182.                                  The Copy Command
  183.                                  The Extract Command
  184.                                  The FindPosn Command
  185.                                    The Plain String Find
  186.                                    Using a Single Decapsulator
  187.                                    The Encapsulated String Find
  188.                                    Control Settings
  189.                                    Insoluble Searches
  190.                                    Null Decapsulators
  191.                                    Finding The Last Word
  192.                                    Who Needs This?
  193.  
  194.  
  195.     Date Commands  . . . . . . . General Discussion
  196.                                    The POMDATE.CFG File
  197.                                    Date Formats
  198.                                  The Today Command
  199.                                  The Date Command
  200.                                  The MonthNum Command
  201.                                  The ZeroDate Command
  202.  
  203.  
  204.     Calculation Commands . . . . Calc, CalcReal, CalcBits
  205.  
  206.  
  207.     Input Preprocessors  . . . . Split, Chop
  208.  
  209.  
  210.     Lookup Commands  . . . . . . The LookUp Command
  211.                                    Search Method
  212.                                    Limitations
  213.                                    Null Lines and Comments
  214.                                    Multiple Columns
  215.                                    LookUp Versus Remap
  216.                                  The LookFile Command
  217.                                  The LookCols Command
  218.                                  The LookSpec Command
  219.  
  220.  
  221.     Data Converters  . . . . . . The MakeData Command
  222.                                    Creating Binary Data
  223.                                    Converting Dates
  224.                                    Practical Considerations
  225.                                  The MakeText Command
  226.                                    Converting Binary Data
  227.                                    Converting Dates
  228.                                    Practical Considerations
  229.  
  230.     Miscellaneous Commands . . . The Erase Command
  231.                                  The GetEnv Command
  232.                                    Disappearing Environment Variables
  233.                                    Examples
  234.                                  The Log Command
  235.                                  The MsgWait Command
  236.                                    Standard Behaviour
  237.                                    Setting a Time-Out Delay
  238.                                    Color Cues
  239.                                    Key Stacking
  240.                                    Exceptions
  241.                                    A Word of Caution
  242.                                  The Pause Command
  243.                                  The Sound Command
  244.                                    The LISTEN Utility
  245.                                    Changing the Error Message Sound
  246.                                  The Trace Command
  247.  
  248.  
  249.     Terms . . . .  . . . . . . . Values
  250.                                  Delimiters
  251.                                  Illegal Characters
  252.                                  Using Comparators
  253.                                  Predefined Data Types
  254.  
  255.  
  256.     Techniques . . . . . . . . . Uninitialized and Persistent Variables
  257.                                  Inline Incrementing and Decrementing
  258.                                  Line Counters
  259.                                  Tracing
  260.                                  Logging
  261.                                  Quiet Mode
  262.                                  The ShowNum Utility
  263.  
  264.  
  265.     File Handling  . . . . . . . How Parse-O-Matic Searches for a File
  266.                                  How Parse-O-Matic Opens an Output File
  267.                                  Appending to an Output File
  268.                                  Sending Output to a Device
  269.                                  DBF Files
  270.                                  POM and Wildcards
  271.                                  Solving Memory Problems
  272.  
  273.  
  274.     Operational Planning . . . . Effective Use of Batch Files
  275.                                  Running Parse-O-Matic from Another Program
  276.                                  Unattended Operation
  277.                                  Examples
  278.  
  279.  
  280.     Running under Windows  . . . Compatibility
  281.                                  Setting Up for Windows 95
  282.                                  Installing the ShowNum Utility
  283.                                  Long File Names in Win95
  284.  
  285.  
  286.     Licensing  . . . . . . . . . Trial License
  287.                                  Single-User License
  288.                                  Site and Multi-Copy Licenses
  289.                                  LAN and WAN Licenses
  290.                                  Distribution License
  291.                                  Retail License
  292.  
  293.  
  294.  
  295.     ===========================================================================
  296.                                     INTRODUCTION
  297.     ===========================================================================
  298.  
  299.  
  300.                                ----------------------
  301.                                What is Parse-O-Matic?
  302.                                ----------------------
  303.  
  304.     Parse-O-Matic is a programmable file-parser.  Simple enough for even a non-
  305.     programmer to master, it can help out in countless ways.  If you have a
  306.     file you want to edit, manipulate, or change around, Parse-O-Matic may be
  307.     just the tool you need.  Parse-O-Matic can also speed up or automate long
  308.     or repetitive editing tasks.
  309.  
  310.  
  311.                      -----------------------------------------
  312.                      Parse-O-Matic Versus Automatic Converters
  313.                      -----------------------------------------
  314.  
  315.     Parse-O-Matic is not an "automatic file converter".  It will not, for
  316.     example, convert WordPerfect files to MS-Word format, or convert Lotus
  317.     1-2-3 Spreadsheets DIRECTLY to Excel files -- although it can read reports
  318.     from one program and convert them to another format (e.g. comma-delimited),
  319.     which can be imported by the other program.
  320.  
  321.     One advantage of this method (as opposed to automatic file conversion) is
  322.     that you can create an "intelligent" importing procedure, which can make
  323.     decisions and modify data.  You could, for example, eliminate certain types
  324.     of records, tidy up names, convert case, unify fields, make calculations,
  325.     and so on.
  326.  
  327.  
  328.                       ----------------------------------------
  329.                       Why You Need Parse-O-Matic -- An Example
  330.                       ----------------------------------------
  331.  
  332.     There are plenty of programs out there that have valuable data locked away
  333.     inside them.  How do you get that data OUT of one program and into another
  334.     one?
  335.  
  336.     Some programs provide a feature which "exports" a file into some kind of
  337.     generic format.  Perhaps the most popular of these formats is known as a
  338.     "comma-delimited file", which is a text file in which each data field is
  339.     separated by a comma.  Character strings -- which might themselves contain
  340.     commas -- are surrounded by double quotes.  So a few lines from a
  341.     comma-delimited file might look something like this (an export from a
  342.     hypothetical database of people who owe your company money):
  343.  
  344.     "JONES","FRED","1234 GREEN AVENUE", "KANSAS CITY", "MO",293.64
  345.     "SMITH","JOHN","2343 OAK STREET","NEW YORK","NY",22.50
  346.     "WILLIAMS","JOSEPH","23 GARDEN CRESCENT","TORONTO","ON",16.99
  347.  
  348.     Unfortunately, not all programs export or import data in this format.
  349.     Even more frustrating is a program that exports data in a format that is
  350.     ALMOST what you need!
  351.  
  352.     If that's the case, you might decide to spend a few hours in a text editor,
  353.     modifying the export file so that the other program can understand it.  Or
  354.     you might write a program to do the editing for you.  Both solutions are
  355.     time-consuming.
  356.  
  357.     An even more challenging problem arises when a program which has no export
  358.     capability does have the ability to "print" reports to a file.  You can
  359.     write a program to read these files and convert them to something you can
  360.     use, but this can be a LOT of work!
  361.  
  362.  
  363.                             ----------------------------
  364.                             Parse-O-Matic to the Rescue!
  365.                             ----------------------------
  366.  
  367.     Parse-O-Matic is a utility that reads a file, interprets the data, and
  368.     outputs the result to another file.  It can help you "boil down" data to
  369.     its essential information.  You can also use it to convert NEARLY
  370.     compatible import files, or generate printable reports.
  371.  
  372.  
  373.                                     ------------
  374.                                     How It Works
  375.                                     ------------
  376.  
  377.     You need three things:
  378.  
  379.     1) The Parse-O-Matic program
  380.     2) A Parse-O-Matic "POM" file (to tell Parse-O-Matic what to do)
  381.     3) The input file
  382.  
  383.     The input file might be a report or data file from another program, or text
  384.     captured from a communications session.  Parse-O-Matic can handle many
  385.     types of input.  We've provided several sample input files. For example,
  386.     the file XMPDAT02.TXT comes from the AccPac accounting software.  AccPac is
  387.     a great program, but its export capabilities leave something to be desired.
  388.     Parse-O-Matic can help!
  389.  
  390.     To see detailed demonstrations of how various files can be parsed, enter
  391.     START at the DOS prompt (or run START.BAT from Windows or OS/2), then
  392.     select TUTORIAL from the menu.
  393.  
  394.  
  395.                                  -----------------
  396.                                  How To Contact Us
  397.                                  -----------------
  398.  
  399.     If you have any questions about Parse-O-Matic, you can write to us at the
  400.     following address:
  401.  
  402.              Pinnacle Software, CP386, Mount Royal, QC, Canada H3P 3C6
  403.  
  404.     You can also contact us electronically at the following addresses:
  405.  
  406.                         Voice Line: 514-345-9578
  407.                     Free Files BBS: 514-345-8654
  408.                     Internet Email: pinnacl@cam.org
  409.                     World Wide Web: http://www.cam.org/~pinnacl
  410.                         CompuServe: 70154,1577
  411.  
  412.  
  413.  
  414.     ===========================================================================
  415.                                     FUNDAMENTALS
  416.     ===========================================================================
  417.  
  418.  
  419.     This documentation assumes that you are an experienced computer user.  If
  420.     you have trouble, you might ask a programmer to help you -- POM file
  421.     creation is a little like programming!
  422.  
  423.  
  424.                              -------------------------
  425.                              The Parse-O-Matic Command
  426.                              -------------------------
  427.  
  428.     The basic format of the Parse-O-Matic command line is:
  429.  
  430.     POM pom-file input-file output-file
  431.  
  432.     Here is an example, as you would type it at the DOS command line, or as a
  433.     command in a batch file:  POM POMFILE.POM REPORT.TXT OUTPUT.TXT
  434.  
  435.     For a more formal description of the command line, start up POM by typing
  436.     this command at the DOS prompt:  POM
  437.  
  438.  
  439.                                     ------------
  440.                                     The POM File
  441.                                     ------------
  442.  
  443.     The POM file is a text file with a .POM extension.  The following
  444.     conventions are used when interpreting the POM file:
  445.  
  446.     - Null lines and lines starting with a semi-colon (comments) are ignored.
  447.  
  448.     - A POM file may contain up to 750 lines of specifications.
  449.       Comment lines do not count in this total.
  450.  
  451.     A POM file does not rely on "loops" (to use the programming term).  Each
  452.     line or record of the input file is processed by the entire POM file.  If
  453.     you would like this expressed in terms of programming languages, here is
  454.     what POM does:
  455.  
  456.     +-------------------------------------------------------------------------+
  457.     |      START: If there's nothing left in the input file, go to QUIT.      |
  458.     |             Read a line from the input file                             |
  459.     |             Do everything in the POM file                               |
  460.     |             Go to START                                                 |
  461.     |      QUIT:  Tell the user you're finished!                              |
  462.     +-------------------------------------------------------------------------+
  463.  
  464.     The method by which Parse-O-Matic finds the POM file is discussed in the
  465.     section "How Parse-O-Matic Searches for a File".
  466.  
  467.  
  468.                                 -------------------
  469.                                 Padding for Clarity
  470.                                 -------------------
  471.  
  472.     Spaces and tabs between the words and variables in a POM file line are
  473.     generally ignored (except in the case of the "output picture" of the OUT
  474.     and OUTEND commands).  You can use spaces to make the commands in your POM
  475.     files easier to read.
  476.  
  477.     Additionally, in any line in the POM file, the following terms are ignored:
  478.  
  479.     THEN   ELSE
  480.  
  481.     (There is a POM command named ELSE, but Parse-O-Matic can tell that this is
  482.     not "padding".)
  483.  
  484.     Finally, the equals ("=") character is ignored if it is found in a place
  485.     where no comparison is taking place.  This will be demonstrated below.
  486.  
  487.     You can use these techniques to make your POM files easier to read.  For
  488.     example, the IF command can be written in several ways:
  489.  
  490.     Very terse:          IF PRICE = "0.00" BONUS "0.00" "1.00"
  491.  
  492.     Padded with spaces:  IF PRICE = "0.00"   BONUS   "0.00"   "1.00"
  493.  
  494.     Fully padded:        IF PRICE = "0.00" THEN BONUS = "0.00" ELSE "1.00"
  495.  
  496.     In the last example, the first equals sign ("=") is a "comparator".  (For
  497.     details about comparators, see the section entitled "Using Comparators".)
  498.     The second equals sign is not really required, but it does make the line
  499.     easier to understand.
  500.  
  501.  
  502.                                   ----------------
  503.                                   A Simple Example
  504.                                   ----------------
  505.  
  506.     Let's say you have a text file called NAMES.TXT that looks like this:
  507.  
  508.     WILLIAMS   JACK
  509.     SMITH      JOHNNY
  510.     JOHNSON    MARY
  511.     :          :
  512.     Column 1   Column 12
  513.  
  514.     Now let's say you want to switch the columns, so that the first name
  515.     appears first.  Your first step is to create a file using a text editor.
  516.     The file would look like this:
  517.  
  518.     SET    last  = $FLINE[ 1 10]
  519.     SET    first = $FLINE[12 17]
  520.     PAD    first "R" " " "10"
  521.     OUTEND |{first} {last}
  522.  
  523.     The first two lines tell Parse-O-Matic to which text to extract from each
  524.     input line.  For the first line of the input file, the variable named
  525.     'last' will be given the value "WILLIAMS  ".  You will notice there are two
  526.     spaces at the end.  That is because we take every character from position 1
  527.     to position 10 -- which in this case includes two spaces.
  528.  
  529.     The PAD line adds enough spaces on the right side of the variable named
  530.     'first' to make sure that it is 10 characters long.  The OUTEND command
  531.     sends the two variables to the output file.
  532.  
  533.     Save the file with the name TEST.POM and exit your text editor.  At the DOS
  534.     prompt, enter this command:
  535.  
  536.     POM TEST.POM NAMES.TXT OUTPUT.TXT
  537.  
  538.     This will run the POM file (TEST.POM) on every line of the input file
  539.     (NAMES.TXT) and place the output in the file OUTPUT.TXT, which will then
  540.     look like this:
  541.  
  542.     JACK       WILLIAMS
  543.     JOHNNY     SMITH
  544.     MARY       JOHNSON
  545.     :          :
  546.     Column 1   Column 12
  547.  
  548.     Of course, for such a simple task, it would be easier to switch the columns
  549.     yourself, using a text editor.  But when you are dealing with large amounts
  550.     of data, and want to guard against typing errors, Parse-O-Matic can save
  551.     you a lot of time, effort and risk.  It also lets you automate editing
  552.     operations that you perform frequently.
  553.  
  554.  
  555.  
  556.     ===========================================================================
  557.                                   QUICK REFERENCE
  558.     ===========================================================================
  559.  
  560.  
  561.                                 --------------------
  562.                                 Command Descriptions
  563.                                 --------------------
  564.  
  565.     This manual's explanations of the commands are grouped by related
  566.     functions, in the following order:
  567.  
  568.  
  569.     ---------------------------------------------------------------------------
  570.     BASIC COMMANDS
  571.     ---------------------------------------------------------------------------
  572.     SET      Assigns a value to a variable
  573.     IF       Conditionally assigns a value to a variable
  574.  
  575.     ---------------------------------------------------------------------------
  576.     OUTPUT COMMANDS
  577.     ---------------------------------------------------------------------------
  578.     OFILE    Specify output file or device
  579.     OUT      Sends text and variables to the output file
  580.     OUTEND   Like OUT but adds a new line at the end (Carriage Return/Linefeed)
  581.     OUTHDG   Sets up title lines to appear at the top of a report or each page
  582.     OUTPAGE  Starts a new page
  583.     PAGELEN  Sets the page length for a report
  584.  
  585.     ---------------------------------------------------------------------------
  586.     INPUT COMMANDS
  587.     ---------------------------------------------------------------------------
  588.     GET      Manually reads bytes from the input file
  589.     GETTEXT  Manually reads bytes from the input file and converts them to text
  590.     READNEXT Moves to next input line but retains your place in the POM file
  591.  
  592.     ---------------------------------------------------------------------------
  593.     INPUT FILTERS
  594.     ---------------------------------------------------------------------------
  595.     MINLEN   Sets the minimum length required for an input line to be processed
  596.     IGNORE   Ignores an input line that meets the specified condition
  597.     ACCEPT   Accepts an input line that meets the specified condition
  598.  
  599.     ---------------------------------------------------------------------------
  600.     FLOW CONTROL COMMANDS
  601.     ---------------------------------------------------------------------------
  602.     BEGIN    Defines the conditions for processing the code block
  603.     ELSE     Defines the start of code to be processed if the BEGIN fails
  604.     END      Marks the end of a BEGIN/END or BEGIN/ELSE/END code block
  605.     AGAIN    Conditionally returns to the corresponding BEGIN command
  606.     DONE     Reads the next input line and starts at the top of the POM file
  607.     NEXTFILE Skips the current input file and proceeds to the next one
  608.     HALT     Terminates all processing if a given condition exists
  609.     PROLOGUE Defines code block to run before input lines are processed
  610.     EPILOGUE Defines code block to run after  input lines are processed
  611.  
  612.     ---------------------------------------------------------------------------
  613.     VARIABLE MODIFIERS
  614.     ---------------------------------------------------------------------------
  615.     TRIM     Removes a character from the left, right or all of a variable
  616.     PAD      Centers, or left/right-justifies variable to a specified width
  617.     CHANGE   Replaces all occurrences of a string in a variable
  618.     PROPER   Properizes a variable (e.g. "JOHN SMITH" becomes "John Smith")
  619.     INSERT   Inserts a string on the left or right, or at a "found" position
  620.     APPEND   Concatenates several variables into one variable
  621.     CVTCASE  Converts a value to uppercase or lowercase
  622.     MAPFILE  reads a file containing data transformations for REMAP
  623.     REMAP    transforms sub-strings into other strings
  624.  
  625.     ---------------------------------------------------------------------------
  626.     FREE-FORM COMMANDS
  627.     ---------------------------------------------------------------------------
  628.     PARSE    Obtains a variable found between delimiters in free-form data
  629.     PEEL     Works like PARSE, but removes the "found" text from the data
  630.     
  631.     ---------------------------------------------------------------------------
  632.     POSITIONAL COMMANDS
  633.     ---------------------------------------------------------------------------
  634.     SETLEN   Sets a variable according to the length of a value
  635.     DELETE   Removes a range of characters from a variable
  636.     COPY     Copies a range of characters from a value to a variable
  637.     EXTRACT  Like COPY, but removes the characters from the source variable
  638.     FINDPOSN Finds the starting or ending position of a value in another
  639.  
  640.     ---------------------------------------------------------------------------
  641.     DATE COMMANDS
  642.     ---------------------------------------------------------------------------
  643.     TODAY    Sets a variable to today's date, in a variety of formats
  644.     DATE     Sets a given year, month and day, in a variety of formats
  645.     MONTHNUM Sets the month number of a given month, expressed as text
  646.  
  647.     ---------------------------------------------------------------------------
  648.     CALCULATION COMMANDS
  649.     ---------------------------------------------------------------------------
  650.     CALC     Performs arithmetic functions on integer values
  651.     CALCREAL Performs arithmetic functions on decimal values
  652.  
  653.     ---------------------------------------------------------------------------
  654.     INPUT PREPROCESSORS
  655.     ---------------------------------------------------------------------------
  656.     SPLIT    Breaks up a wide text file (more than 255 characters)
  657.     CHOP     Breaks up a fixed-record-length file
  658.  
  659.     ---------------------------------------------------------------------------
  660.     LOOKUP COMMANDS
  661.     ---------------------------------------------------------------------------
  662.     LOOKUP   Looks up a word in another file and returns a corresponding value
  663.     LOOKFILE Specifies the file that the LOOKUP command will use (see also /L)
  664.     LOOKCOLS Specifies the format of the look-up file
  665.     LOOKSPEC Controls the behaviour of the LOOKUP command
  666.  
  667.     ---------------------------------------------------------------------------
  668.     DATA CONVERTERS
  669.     ---------------------------------------------------------------------------
  670.     MAKEDATA Converts text into binary format
  671.     MAKETEXT Converts binary format into text
  672.  
  673.     ---------------------------------------------------------------------------
  674.     MISCELLANEOUS COMMANDS
  675.     ---------------------------------------------------------------------------
  676.     ERASE    Deletes a file
  677.     GETENV   obtains a system environment variable (e.g. PATH)
  678.     LOG      Adds a line to the processing log
  679.     MSGWAIT  controls the behaviour of error messages
  680.     PAUSE    Delays the specified number of milliseconds
  681.     SOUND    Makes a noise or sets the noise generated by error messages
  682.     TRACE    Traces a variable (results saved in the text file POM.TRC)
  683.  
  684.  
  685.                                   ---------------
  686.                                   Command Formats
  687.                                   ---------------
  688.  
  689.     ----------------------------------  ---------------------------------------
  690.     COMMAND FORMATS                     EXAMPLE
  691.     ----------------------------------  ---------------------------------------
  692.     ACCEPT   val c val                  ACCEPT   $FLINE[1 3] = "YES"
  693.     AGAIN    [val c val]                AGAIN    linecntr #< "3"
  694.     APPEND   var val val [val [val]]    APPEND   name first last
  695.     BEGIN    [val c val]                BEGIN    linecntr #< "3"
  696.     CALC     var num operation num      CALC     total total "+" sold
  697.     CALCBITS var char operation char    CALCBITS z byte1 "XOR" $80
  698.     CALCREAL var num operation num      CALCREAL salary hours "*" rate
  699.     CHANGE   var val val                CHANGE   date "/" "-"
  700.     CHOP     from to [,from to] [...]   CHOP     1 250, 251 300
  701.     COPY     var val from [to]          COPY     x $FLINE "3" "5"
  702.     CVTCASE  var val [ctl]              CVTCASE  x $FLINE "LA"
  703.     DATE     var num num num [ctl]      DATE     x "98" "12" "31"
  704.     DELETE   var from [to]              DELETE   x "3" "5"
  705.     DONE     [val c val]                DONE     $FLINE = "End Data"
  706.     ELSE                                ELSE
  707.     END                                 END
  708.     EPILOGUE                            EPILOGUE
  709.     ERASE    file                       ERASE    "C:\MYFILES\OUT.TXT"
  710.     EXTRACT  var var from [to]          EXTRACT  x $FLINE "15" "30"
  711.     FINDPOSN var val left [right [ctl]] FINDPOSN x $FLINE "2*/"
  712.     GET      var ctl [ctl [ctl]]        GET      x #0 "END" "I"
  713.     GETENV   var val                    GETENV   x "COMSPEC"
  714.     GETTEXT  var ctl [ctl]              GETTEXT  date "WORD" "DATE"
  715.     HALT     val c val val [ctl]        HALT     x = y "Item repeated"
  716.     IF       val c val var val [val]    IF       x = "Y" THEN z = "N"
  717.     IGNORE   val c val                  IGNORE   price = "0.00"
  718.     INSERT   var ctl val                INSERT   price "L" "$"
  719.     LOG      val c val val [val [val]]  LOG      x = y "Item repeated"
  720.     LOOKCOLS num num num num            LOOKCOLS "1" "3" "8" "255"
  721.     LOOKFILE file                       LOOKFILE "C:\TABLES\DATA.TBL"
  722.     LOOKSPEC ctl ctl ctl                LOOKSPEC "Y" "N" "N"
  723.     LOOKUP   var val                    LOOKUP   phonenum "FRED JONES"
  724.     MAKEDATA var val ctl                MAKEDATA x "255" "BYTE"
  725.     MAKETEXT var val ctl                MAKETEXT z x "BYTE"
  726.     MAPFILE  file val [ctl]             MAPFILE  "XYZ.MPF" "XYZ" "ANYCASE"
  727.     MINLEN   num [num]                  MINLEN   "15" "1"
  728.     MONTHNUM var val                    MONTHNUM x "February"
  729.     MSGWAIT  num                        MSGWAIT  "60"
  730.     NEXTFILE [val c val]                NEXTFILE $FLINE = "End File"
  731.     OFILE    file                       OFILE    "C:\MYFILES\OUT.TXT"
  732.     OUT      [val c val] |pic           OUT      z = "X" |{price}
  733.     OUTEND   [val c val] |pic           OUTEND   z = "X" |{$FLINE}
  734.     OUTHDG   val                        OUTHDG   "LIST OF EMPLOYEES"
  735.     OUTPAGE  [val c val]                OUTPAGE  partnum <> oldpartnum
  736.     PAD      var ctl char num           PAD      sernum "L" "0" "10"
  737.     PAGELEN  num [ctl]                  PAGELEN  "66" "N"
  738.  
  739.     PARSE    var val left right [ctl]   PARSE    x $FLINE "2*(" "3*)" "I"
  740.     PAUSE    val                        PAUSE    "1000"
  741.     PEEL     var var left right [ctl]   PEEL     x $FLINE "2*(" "3*)" "I"
  742.     PROLOGUE                            PROLOGUE
  743.     PROPER   var [ctl [file]]           PROPER   custname "I" "XY.PEF"
  744.     READNEXT [val c val]                READNEXT $FLINE[1 5] = "NOTE:"
  745.     REMAP    var [val]                  REMAP    $FLINE "BIN2CODE"
  746.     SET      var val                    SET      name $FLINE[20 26]
  747.     SETLEN   var val                    SETLEN   length custname
  748.     SOUND    ctl                        SOUND    "BUZZ"
  749.     SPLIT    from to [,from to] [...]   SPLIT    1 250, 251 300
  750.     TODAY    var [ctl]                  TODAY    x "?y/?n/?d"
  751.     TRACE    var                        TRACE    price
  752.     TRIM     var ctl char               TRIM     price "R" "$"
  753.     ZERODATE val val val                ZERODATE "1753" "12" "31"
  754.     ----------------------------------  ---------------------------------------
  755.  
  756.     The following conventions are used in the preceding table:
  757.  
  758.     c      Comparator (if omitted, defaults to "equals" comparison)
  759.     char   Variable or literal: must be a single byte or character
  760.     ctl    Variable or literal: command control specifications
  761.     file   File name (see "How Parse-O-Matic Searches for a File")
  762.     from   Variable or literal: a starting character position (see Note #1)
  763.     left   Variable or literal: see "Decapsulators"
  764.     num    Variable or literal: must contain a number (see Note #1)
  765.     pic    Output picture used by OUT and OUTEND
  766.     right  Variable or literal: see "Decapsulators"
  767.     to     Variable or literal: an ending position (see Note #1)
  768.     val    Variable or literal whose value is being read
  769.     var    Variable that is being set
  770.     [xxx]  Square brackets indicate optional items
  771.  
  772.     Note #1:  Tabs, spaces and commas are stripped from numeric values
  773.  
  774.     The commands are explained in detail in the following section.  A summary
  775.     of the commands and default settings appear, as comments, in the file
  776.     QUICKREF.POM.  You can copy these comments into your own POM file as
  777.     a convenient quick reference.
  778.  
  779.  
  780.  
  781.     ===========================================================================
  782.                                    BASIC COMMANDS
  783.     ===========================================================================
  784.  
  785.  
  786.                                   ---------------
  787.                                   The SET Command
  788.                                   ---------------
  789.  
  790.     FORMAT:        SET var1 value1
  791.  
  792.     PURPOSE:       SET assigns a value1 to a the variable var1.
  793.  
  794.     ALTERNATIVES:  The COPY command.
  795.  
  796.     The usual reason to use the SET command is to set a variable from the input
  797.     line (represented by the variable $FLINE) prior to cleaning it up with
  798.     TRIM. For example, if the input line looked like this:
  799.  
  800.     JOHN       SMITH     555-1234   322 Westchester Lane    Architect
  801.     |          |         |          |                       |
  802.     Column 1   Col 12    Col 22     Col 33                  Col 57
  803.  
  804.     then we could extract the last name from the input line with these two POM
  805.     commands:
  806.  
  807.     SET  NAME = $FLINE[12 21]      (Sets the variable from the input line)
  808.     TRIM NAME  "R"  " "            (Trims any spaces on the right side)
  809.  
  810.     SET would first set the variable NAME to this value:     "SMITH     "
  811.     After the TRIM, the variable NAME would have the value:  "SMITH"
  812.  
  813.     You will also use SET if you plan to include a portion of text string in
  814.     the output, since the OUT and OUTEND commands do not recognize substrings
  815.     after the "|" marker; they only recognize plain text and complete
  816.     variables.
  817.  
  818.  
  819.                                    --------------
  820.                                    The IF Command
  821.                                    --------------
  822.  
  823.     FORMAT:        IF value1 [comparator] value2 var1 value3 [value4]
  824.  
  825.     PURPOSE:       If value1 equals value2, var1 is set to value3.  Otherwise,
  826.                    it is set to value4 (if value4 is missing, nothing is done,
  827.                    and var1 is not changed).
  828.  
  829.     NOTES:         For an explanation of comparators, see "Using Comparators".
  830.                    In the following explanation, we will demonstrate the
  831.                    command using only the "literally identical" ("=")
  832.                    comparator.
  833.  
  834.     ALTERNATIVES:  The BEGIN command
  835.  
  836.     Here is an example of the IF command...
  837.  
  838.     SET  EARNING = $FLINE[20 23]
  839.     IF   EARNING = "0.00" THEN BONUS = "0.00" ELSE "1.00"
  840.  
  841.     This obtains the value between columns 20 and 26, then checks if it equals
  842.     "0.00".  If it does, the variable BONUS is set to 0.00.  If not, BONUS is
  843.     set to "1.00".  The "THEN" and "ELSE" are "padding" and can be omitted.
  844.  
  845.  
  846.     ===========================================================================
  847.                                   OUTPUT COMMANDS
  848.     ===========================================================================
  849.  
  850.  
  851.                                  -----------------
  852.                                  The OFILE Command
  853.                                  -----------------
  854.  
  855.     FORMAT:        OFILE value1
  856.  
  857.     PURPOSE:       OFILE specifies a new output file or device.
  858.  
  859.     PARAMETERS:    value1 is the name of the output file (or device)
  860.  
  861.     ALTERNATIVES:  Specify the name on the POM command line.
  862.  
  863.     SEE ALSO:      "How Parse-O-Matic Opens an Output File"
  864.                    "Sending Output to a Device"
  865.  
  866.     When you start up Parse-O-Matic, you can specify the name of the output
  867.     file on the command line.  For example:
  868.  
  869.     POM MYPOM.POM INPUT.TXT OUTPUT.TXT
  870.  
  871.     In this case, the output file is named OUTPUT.TXT.  All data from the
  872.     output commands (OUT, OUTEND etc.) are sent to this file.  If you omit the
  873.     output file name from the POM command, like this:
  874.  
  875.     POM MYPOM.POM INPUT.TXT
  876.  
  877.     then Parse-O-Matic assumes the output file is named POMOUT.TXT (in the
  878.     current directory).
  879.  
  880.     Once the name of the output file has been determined, Parse-O-Matic will
  881.     use that file until it is changed, using the OFILE command.  For example:
  882.  
  883.     OFILE "C:\XYZ.TXT"
  884.  
  885.     This will change the output file to C:\XYZ.TXT.  If the file already
  886.     exists, it will be renamed with a BAK extension.  However, you can tell
  887.     Parse-O-Matic to append to the end of an existing file by placing a plus
  888.     sign in front of the file name:
  889.  
  890.     OFILE "+C:\XYZ.TXT"
  891.  
  892.     (See "Appending to Output Files" and "POM and Wildcards" for additional
  893.     details on appending to output files).
  894.  
  895.  
  896.                             ---------------------------
  897.                             The OUT and OUTEND Commands
  898.                             ---------------------------
  899.  
  900.     FORMAT:        OUT[END] [value1 [comparator] value2] |output-picture
  901.  
  902.     PURPOSE:       The OUT command generates output without an end-of-line
  903.                    (i.e. carriage return and linefeed characters).
  904.                    The OUTEND command generates output and also adds an
  905.                    end-of-line.
  906.  
  907.     NOTES:         For an explanation of comparators, see "Using Comparators".
  908.                    In the following explanation, we will demonstrate the
  909.                    command using only the "literally identical" ("=")
  910.                    comparator.
  911.  
  912.     When value1 equals value2, a line is sent to the output file, according to
  913.     the output picture.  Within the output picture, all text is taken literally
  914.     (i.e. " is taken to mean literally that -- a quotation mark character).
  915.  
  916.     The only exception to this is variable names, which are identified by the
  917.     { and } characters.  For example, a POM file that contained the following
  918.     single line:
  919.  
  920.     OUTEND "X" = "X" |{$FLINE}
  921.  
  922.     would simply output every line from the input file (not very useful!).
  923.  
  924.     The "X" = "X" part of the command is the comparison which controls when
  925.     output occurs.  In the example above, both values being compared are the
  926.     same, so output will always occur.
  927.  
  928.     You can not use substrings after the "|" marker.  Thus, the following line
  929.     is NOT legal:  OUTEND $FLINE[1 3] = "IBM" |{$FLINE[1 15]}
  930.  
  931.     The correct way to code this is as follows:
  932.  
  933.     SET CODE = $FLINE[1 15]
  934.     OUTEND $FLINE[1 3] = "IBM" |{CODE}
  935.  
  936.     This outputs the first 15 characters of any line that contains the letters
  937.     "IBM" in the first three positions.
  938.  
  939.  
  940.                                  ------------------
  941.                                  The OUTHDG Command
  942.                                  ------------------
  943.  
  944.     FORMAT:        OUTHDG value1
  945.  
  946.     PURPOSE:       OUTHDG is used to place text headers in your output.
  947.  
  948.     ALTERNATIVES:  The OUTEND command, used in conjunction with PROLOGUE.
  949.  
  950.     SEE ALSO:      "The PageLen Command" and "The OutPage Command"
  951.  
  952.     If you were parsing data to create an employee report, you might use OUTHDG
  953.     like this:
  954.  
  955.     SET EMPNUM = $FLINE[ 1  5]
  956.     SET NAME   = $FLINE[10 28]
  957.     SET PHONE  = $FLINE[30 45]
  958.     OUTHDG "EMPL#  NAME                PHONE NUMBER"
  959.     OUTHDG "-----  ------------------- ------------"
  960.     OUTEND |{EMPNUM} {NAME} {PHONE}
  961.  
  962.     The value following the OUTHDG command is sent to the output file only
  963.     once.  That is to say, after an OUTHDG sends a value to the output file,
  964.     subsequent encounters with that OUTHDG command are ignored -- unless the
  965.     PAGELEN command is used.
  966.  
  967.     To specify a blank line in a heading, use the following command:  OUTHDG ""
  968.  
  969.     If your output is bound for a continuous-paper printer (e.g. a dot-matrix
  970.     printer with tractor feed), you may find it useful to use one or more blank
  971.     lines at the beginning of the header, in order to skip over the perforation
  972.     in the paper.
  973.  
  974.                                 -------------------
  975.                                 The OUTPAGE Command
  976.                                 -------------------
  977.  
  978.     FORMAT:        OUTPAGE  [value1 [comparison] value2]
  979.  
  980.     PURPOSE:       Sends a page eject to the output file (or device).
  981.  
  982.     NOTES:         For an explanation of comparators, see "Using Comparators".
  983.  
  984.     SEE ALSO:      "The Pagelen Command" and "The OutHdg Command"
  985.  
  986.     If the comparison in the OUTPAGE command is true, or if it is omitted,
  987.     OUTPAGE will send a "page eject" to the output file or device.  (See
  988.     "Sending Output to a Device")  Some exceptions apply, however.  The page
  989.     eject is not sent under the following circumstances:
  990.  
  991.     - If the comparison is false (e.g. OUTPAGE "Y" = "N")
  992.  
  993.     - If the page length is set to "0" (the default).  Use the PAGELEN command
  994.       to specify a different page length.
  995.  
  996.     - If the output file is not yet open.  That is to say, if no output has
  997.       been sent to the output via one of the other output commands (e.g. OUT,
  998.       OUTEND, OUTHDG), then OUTPAGE will do nothing. (See "How Parse-O-Matic
  999.       Opens an Output File")
  1000.  
  1001.     - If the output is already at the top of a page.
  1002.  
  1003.     If form feeds are enabled (via the PAGELEN command), OUTPAGE sends a
  1004.     page eject by sending a Form Feed character (ASCII 12) to the output.
  1005.  
  1006.     If form feeds are not enabled, OUTPAGE sends blank lines (i.e. linefeeds)
  1007.     until the requisite number of lines appear on the page.
  1008.  
  1009.     OUTPAGE does NOT automatically place OUTHDG text at the top of the page.
  1010.     OUTHDG text is not "stored"; it is executed in the POM file at the place
  1011.     it occurs.  Here is an example of using OUTPAGE and OUTHDG together:
  1012.  
  1013.     PAGELEN "55" "Y"
  1014.     SET partnum = $FLINE[ 1  7]
  1015.     SET descrip = $FLINE[12 60]
  1016.     OUTPAGE partnum <> oldpartnum
  1017.     OUTHDG |PARTNUM  DESCRIPTION
  1018.     OUTHDG |-------  -----------
  1019.     OUTEND |{partnum}  {descrip}
  1020.     SET    oldpartnum = partnum
  1021.  
  1022.     This will generate a new page, complete with headings, when the partnum
  1023.     variable is different from the oldpartnum variable.  Also, because of the
  1024.     interaction between OUTHDG and PAGELEN, they headings will appear on a new
  1025.     page if you run out of room on the current page.
  1026.  
  1027.  
  1028.                                 -------------------
  1029.                                 The PAGELEN Command
  1030.                                 -------------------
  1031.  
  1032.     FORMAT:        PAGELEN value1 [value2]
  1033.  
  1034.     PURPOSE:       The PAGELEN command specifies the length of the output page.
  1035.  
  1036.     PARAMETERS:    value1 is the page length
  1037.                    value2 specifies if form feeds should be used
  1038.  
  1039.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  1040.  
  1041.     DEFAULTS:      value2 = "Y"
  1042.  
  1043.     When text is sent to an output file by OUTHDG and OUTEND, the lines are
  1044.     counted.  The default value for page length is zero, which means that the
  1045.     output is a single page of infinite length.  As such, OUTHDG headings
  1046.     appear only the first time they are encountered, and OUTPAGE commands
  1047.     are ignored.
  1048.  
  1049.     If you specify a page length greater than zero, OUTHDG headings become
  1050.     re-enabled once the specified number of output lines have been generated,
  1051.     or after an OUTPAGE command is performed.  A typical value is as follows:
  1052.  
  1053.     PAGELEN "55"
  1054.  
  1055.     This is an ideal page length for most laser printers.  Dot matrix printers
  1056.     typically use a page length of 66.
  1057.  
  1058.     Parse-O-Matic inserts a "form feed" (ASCII 12) character between pages.
  1059.     You can turn this off, however, by specifying the page length this way:
  1060.  
  1061.     PAGELEN "66" "N"
  1062.  
  1063.     The "N" specification means, "No, don't use form feeds".  Another
  1064.     acceptable value is "Y", meaning "Yes, use form feeds", but since this is
  1065.     the default, you do not have to specify it.
  1066.  
  1067.  
  1068.  
  1069.     ===========================================================================
  1070.                                    INPUT COMMANDS
  1071.     ===========================================================================
  1072.     
  1073.  
  1074.                                   ---------------
  1075.                                   The GET Command
  1076.                                   ---------------
  1077.  
  1078.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  1079.  
  1080.     FORMAT:        GET var1 value1 [value2]         (Variable length records)
  1081.                    GET var1 value1 "END" [value3]   (Delimiter-terminated data)
  1082.  
  1083.     PURPOSE:       Manually reads bytes from the input file.
  1084.  
  1085.     NOTES:         Data is normally read automatically from the input file.
  1086.                    GET is used only when you want precise control of the
  1087.                    reading process.  GET works only with files whose format
  1088.                    is defined by the CHOP command.  (You can read a file
  1089.                    a byte at a time by using CHOP 1-1 in your POM file.
  1090.                    You can also use CHOP 0 to do all reading manually.)
  1091.  
  1092.     SEE ALSO:      "The Chop Command"
  1093.  
  1094.     The GET command is especially helpful for:
  1095.  
  1096.     1) Variable length records
  1097.     2) Delimiter-terminated data (such as zero-terminated text strings)
  1098.  
  1099.     These methods are described in detail below.
  1100.  
  1101.  
  1102.     Variable Length Records
  1103.     -----------------------
  1104.  
  1105.     FORMAT:        GET var1 value1 [value2]
  1106.  
  1107.     PURPOSE:       Reads a variable-length record.
  1108.  
  1109.     PARAMETERS:    var1    is the variable being set
  1110.                    value1  specifies how many bytes to read, expressed as:
  1111.                            A value in text format (example:  GET x "10")
  1112.                            A predefined data type (example:  GET x "INTEGER")
  1113.                            A value in byte format (example:  GET x len "BYTE")
  1114.                    value2  specifies the data representation used by value1
  1115.                            This can be "TEXT" (the default) or "BYTE"
  1116.  
  1117.     NUMERICS:      Tabs, spaces and commas are stripped from value1, if it is
  1118.                    numeric, and in text format
  1119.  
  1120.     DEFAULTS:      value2 = "TEXT"
  1121.  
  1122.     SEE ALSO:      "Predefined Data Types"
  1123.  
  1124.     GET can read up to 255 bytes into a variable, as specified by value1.
  1125.     For example:
  1126.  
  1127.     GET xyz "10"
  1128.  
  1129.     This reads 10 bytes from the input file into the xyz variable, and advances
  1130.     the file pointer.  That is to say, after the GET command shown above is
  1131.     executed, the next data Parse-O-Matic reads will be 10 bytes further along.
  1132.  
  1133.     If the requested number of bytes is not available in the input file,
  1134.     Parse-O-Matic terminates with an error message.
  1135.  
  1136.     In a typical application, variable-length data is preceded in the input
  1137.     file by a byte that gives its length.  You can read the length, then use
  1138.     it directly, as follows:
  1139.  
  1140.     GET len "1" "TEXT"               <-- Get the length byte
  1141.     GET xyz len "BYTE"               <-- Read in the data
  1142.  
  1143.     In the first command, the word "TEXT" means that the length specification
  1144.     (i.e. "1") is plain text.  ("TEXT" is the default, so you can omit it.)
  1145.  
  1146.     In the second command, GET reads len bytes from the input file.  The word
  1147.     "BYTE" means that the length specification is a binary number, not a text
  1148.     string.
  1149.  
  1150.     To clarify this, let us assume that the input file contains a length byte
  1151.     (say hex 4F, which equals 79 in decimal).  This is followed by 79 bytes of
  1152.     data.  The first GET command (GET len "1") reads in the length byte (hex 4F
  1153.     or decimal 79).  The second GET command (GET xyz len "BYTE") reads 79 bytes
  1154.     and places the result in the xyz variable.
  1155.  
  1156.     The maximum variable length that a single GET command can handle is 255
  1157.     bytes (i.e. the largest number represented by a single byte).
  1158.  
  1159.     Here are some additional examples of the GET command:
  1160.  
  1161.     SAMPLE COMMAND     EXPLANATION
  1162.     -----------------  -----------
  1163.     GET x "5" "TEXT"   Reads 5 bytes into the x variable
  1164.     GET x "5"          Same as above (since "TEXT" is the default)
  1165.     GET x len          In this case, len must contain a text number (e.g. "7")
  1166.     GET x len "BYTE"   In this case, len must be a byte (i.e. binary format)
  1167.  
  1168.     When the number is in "TEXT" format, spaces and tabs are ignored. Thus, the
  1169.     following command is valid:
  1170.  
  1171.     GET abc " 5 " "TEXT"
  1172.  
  1173.     You can also specify the length of the data as a predefined data type (see
  1174.     "Predefined Data Types" and "The MakeData Command").  Some examples...
  1175.  
  1176.     SAMPLE COMMAND     EXPLANATION
  1177.     -----------------  -----------
  1178.     GET x "INTEGER"    Reads in an integer value (2 bytes long)
  1179.     GET x "SHORTINT"   Reads in a short integer value (1 byte long)
  1180.     GET x "BYTE"       Reads in a byte value (1 byte long)
  1181.     GET x "LONGINT"    Reads in a long integer (4 bytes long)
  1182.     GET x "REAL"       Reads in a real value (6 bytes long)
  1183.     GET x "REAL 2"     Same as above (the decimal precision value 2 is ignored)
  1184.  
  1185.     TECHNICAL NOTE:  In some applications, you will find that a variable-length
  1186.     record may be followed by a "noise" byte. This can occur if the program
  1187.     that created the input file "aligns data to word boundaries" and the record
  1188.     you are reading has an odd number of bytes.  In such case, your POM file
  1189.     must determine (using CALC commands) if the length byte is odd or even, and
  1190.     react accordingly.
  1191.  
  1192.  
  1193.     Delimiter-Terminated Data
  1194.     -------------------------
  1195.  
  1196.     FORMAT:        GET var1 value1 "END" [value3]
  1197.  
  1198.     PURPOSE:       Reads delimiter-terminated data from the input file.
  1199.  
  1200.     PARAMETERS:    var1    is the variable being set
  1201.                    value1  is the terminating character you are searching for
  1202.                    "END"   means you are searching for a terminating character
  1203.                    value3  is "I" (for Include) or "X" (for eXclude)
  1204.  
  1205.     DEFAULTS:      value3 = "X"
  1206.  
  1207.     ALTERNATIVES:  The PARSE and PEEL commands
  1208.                    The FINDPOSN command used with the COPY command
  1209.  
  1210.     One common way to represent variable-length text data in a file is to
  1211.     terminate the text string with the null (ASCII 0) character.  You can
  1212.     read in this kind of data with the GET command, as follows:
  1213.  
  1214.     GET abc #0 "END"           <-- #0 means ASCII zero (See "Values")
  1215.  
  1216.     This reads the input file until the null (ASCII 0) character is found, or
  1217.     until 255 characters have been read in (whichever comes first).
  1218.  
  1219.     The terminating character is not included in the string unless you
  1220.     explicitly request it.  There are two forms of GET command that control
  1221.     this behaviour:
  1222.  
  1223.     GET abc #0 "END" "X"       <-- Exclude the terminating character (default)
  1224.     GET abc #0 "END" "I"       <-- Include the terminating character
  1225.  
  1226.     Here is a sample POM file that reads a data file that consists entirely of
  1227.     zero-terminated strings:
  1228.  
  1229.     CHOP   0                   <-- This means you will handle all file reading
  1230.     GET    abc #0 "END"        <-- Read in the data
  1231.     OUTEND |{abc}              <-- Send the data to the output file
  1232.  
  1233.  
  1234.     Handling Long Strings
  1235.     ---------------------
  1236.  
  1237.     If some of the data is more than 255 characters long, you can handle it as
  1238.     follows:
  1239.  
  1240.     CHOP   0                   <-- Handle all file reading manually
  1241.     GET    data #0 "END" "I"   <-- Include the terminating character
  1242.     SETLEN len data            <-- Get the length of the string
  1243.     COPY   lastchar data len   <-- Get the last character
  1244.     BEGIN  lastchar = #0       <-- Test the last character
  1245.       DELETE data len          <-- Remove the last character (the terminator)
  1246.       OUTEND |{data}           <-- Output the string, and start a new line
  1247.     ELSE
  1248.       OUT    |{data}           <-- Output the string, but stay on the same line
  1249.     END
  1250.  
  1251.     All of the examples given above assume that the terminating character is
  1252.     ASCII 0 (i.e. #0), because this is by far the most common terminator.
  1253.     However, you can use other values, if required:
  1254.  
  1255.     GET data "X" "END"
  1256.  
  1257.     In actual usage, it is not likely that you will find data strings that are
  1258.     terminated by an "X" character, but the capability is there if the need
  1259.     arises.
  1260.  
  1261.                                 -------------------
  1262.                                 The GETTEXT Command
  1263.                                 -------------------
  1264.  
  1265.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  1266.  
  1267.     FORMAT:        GETTEXT var1 value1 [value2]
  1268.  
  1269.     PURPOSE:       Manually reads bytes from the input file, then converts
  1270.                    them into text format.
  1271.  
  1272.     PARAMETERS:    var1   is the variable being set
  1273.                    value1 is the predefined data type in the input file
  1274.                    value2 is the MAKETEXT "convert from" parameter
  1275.  
  1276.     DEFAULTS:      If value2 is omitted, it is assumed to be the same as value1
  1277.  
  1278.     NOTES:         Before studying this command, you should already be familiar
  1279.                    with the GET and MAKETEXT commands.
  1280.  
  1281.     SEE ALSO:      "Predefined Data Types"
  1282.  
  1283.     When reading a binary file, you frequently need to read numeric values then
  1284.     convert them to text.  For example:
  1285.  
  1286.     GET      x "WORD"             <-- Read a two-byte number from the file
  1287.     MAKETEXT y x "WORD"           <-- Convert it into text form
  1288.  
  1289.     You can do both of these operations at once, using the GETTEXT command:
  1290.  
  1291.     GETTEXT  y "WORD"
  1292.  
  1293.     This reads a "WORD" (two binary bytes) from the input file, and then
  1294.     converts it into text (e.g. "1234").
  1295.  
  1296.     You only need to use value2 if you are converting a number to a text-based
  1297.     data type such as "DATE".  For example:
  1298.  
  1299.     ZERODATE "1936" "1" "1"                <-- Set "day zero"
  1300.     GETTEXT  date "LONGINT" "DATE Y/M/?d"  <-- Get and convert a date
  1301.  
  1302.     The GETTEXT command is also helpful if you are reading text data from a
  1303.     fixed-length field, but it is padded with spaces or nulls:
  1304.  
  1305.     GETTEXT  x "80" "TRIMMED"
  1306.  
  1307.     This reads in 80 characters, then removes tabs, spaces and nulls from
  1308.     either end of the string.
  1309.                                                          
  1310.  
  1311.                                 --------------------
  1312.                                 The READNEXT Command
  1313.                                 --------------------
  1314.  
  1315.     FORMAT:        READNEXT [value [comparator] value]
  1316.  
  1317.     PURPOSE:       The READNEXT command gets the next line of the input file
  1318.                    (in other words, it replaces the current $FLINE), while
  1319.                    maintaining your place in the POM file.
  1320.  
  1321.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1322.  
  1323.     SEE ALSO:      "The MinLen Command" and "Line Counters"
  1324.  
  1325.     READNEXT is helpful if you know for certain what type of information the
  1326.     next line will contain.  Here is an example:
  1327.  
  1328.     SET note = ""
  1329.     SET customer = $FLINE[1 20]
  1330.     BEGIN $FLINE ^ "See note below"
  1331.       READNEXT
  1332.       SET note = $FLINE[1 20]
  1333.     END
  1334.     OUTEND |{customer} {note}
  1335.  
  1336.     If the input line contains the words "See note below", Parse-O-Matic will
  1337.     read the next line of the input file (replacing the current $FLINE), thus
  1338.     obtaining the comment about the customer.
  1339.  
  1340.  
  1341.     End of File Conditions
  1342.     ----------------------
  1343.  
  1344.     If you do a READNEXT at the end of the input file, READNEXT will set $FLINE
  1345.     to null ("").  The POM file will continue processing.
  1346.  
  1347.  
  1348.     Optional Comparisons
  1349.     --------------------
  1350.  
  1351.     READNEXT can make a comparison.  This is useful for skipping extraneous
  1352.     lines of input.  For example:
  1353.  
  1354.     READNEXT $FLINE[1 5] = "NOTE:"
  1355.  
  1356.     This obtains the next input line if the current input line starts with
  1357.     "NOTE:".
  1358.  
  1359.  
  1360.     Ignoring Null Lines
  1361.     -------------------
  1362.  
  1363.     By default, READNEXT will read null lines from the input file.  If you want
  1364.     it to ignore null lines, you can use an optional parameter of the MINLEN
  1365.     command to specify a minimum length for the READNEXT command.  For details,
  1366.     see "The MinLen Command".
  1367.  
  1368.     If you are reading a DBF (DBase) file, you can not "ignore null lines",
  1369.     because the data is not in line format.  In such case, you must check a
  1370.     particular field to see if it is null.  (See "DBF Files")
  1371.  
  1372.     If you are using the CHOP or SPLIT commands, it may not be particularly
  1373.     useful to "ignore null lines", since by definition you are requesting a
  1374.     particular number of bytes each time the input is read.  Nevertheless,
  1375.     if you do a READNEXT at the end of the input file, READNEXT will set $FLINE
  1376.     to null (""), and continue processing the POM file.
  1377.  
  1378.  
  1379.     Saving the Previous Line
  1380.     ------------------------
  1381.  
  1382.     When you do a READNEXT, there is no way to return to the previous line of
  1383.     the input file.  If you need it for other work, you should save a copy:
  1384.  
  1385.     SET note = ""
  1386.     SET customer = $FLINE[1 20]
  1387.     SET saveline = $FLINE
  1388.     BEGIN $FLINE ^ "See note below"
  1389.       READNEXT
  1390.       SET note = $FLINE[1 20]
  1391.     END
  1392.     SET    custnum = saveline[22 25]
  1393.     OUTEND |{custnum} {customer} {note}
  1394.  
  1395.     The example above is not very efficient; it would make more sense to
  1396.     extract custnum BEFORE you use READNEXT. However, in some instances you may
  1397.     find it more convenient to save $FLINE before doing a READNEXT.
  1398.  
  1399.  
  1400.     ===========================================================================
  1401.                                    INPUT FILTERS
  1402.     ===========================================================================
  1403.  
  1404.  
  1405.                                  ------------------
  1406.                                  The MINLEN Command
  1407.                                  ------------------
  1408.  
  1409.     FORMAT:        MINLEN value1 [value2]
  1410.  
  1411.     PURPOSE:       MINLEN specifies the minimum length an input line must be to
  1412.                    be considered for parsing.
  1413.  
  1414.     PARAMETERS:    value1 is the minimum input line length
  1415.                    value2 is the minimum length for a READNEXT command
  1416.  
  1417.     NUMERICS:      Tabs, spaces and commas are stripped from value1 and value2
  1418.  
  1419.     DEFAULTS:      value2 = "0"
  1420.  
  1421.     SEE ALSO:      "The ReadNext Command"
  1422.  
  1423.     If you omit the MINLEN command, the minimum length is assumed to be 1.
  1424.     That is to say, all lines 1 character or longer will be processed and
  1425.     shorter lines (null lines in other words) will be ignored.
  1426.  
  1427.     MINLEN is useful for ignoring brief information lines that clutter up a
  1428.     report that you are parsing.  For example, in the sample file EXAMPL02.POM,
  1429.     the MINLEN command is set to 85 to ensure that all lines shorter than 85
  1430.     characters long will be ignored.  This simplifies the coding considerably.
  1431.  
  1432.     The longest allowable input line is 255 characters, unless you use the
  1433.     SPLIT or CHOP command (see "The Split Command" and "The Chop Command").
  1434.  
  1435.     The optional setting value2 specifies the minimum length for a READNEXT
  1436.     command.  If omitted, this value is assumed to be "0", meaning that
  1437.     READNEXT will, by default, read null lines.  If you set value2 to "1",
  1438.     READNEXT will keep reading until it finds an input line of 1 or more
  1439.     characters, or hits the end of file.  The value2 setting has no effect
  1440.     if you are reading a DBF (DBase) file.
  1441.  
  1442.  
  1443.                                  ------------------
  1444.                                  The IGNORE Command
  1445.                                  ------------------
  1446.  
  1447.     FORMAT:        IGNORE value1 [comparator] value2
  1448.  
  1449.     PURPOSE:       When the comparison is true, the input line is ignored and
  1450.                    all further processing on the input line stops.
  1451.  
  1452.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1453.  
  1454.     ALTERNATIVES:  The ACCEPT and BEGIN commands.
  1455.  
  1456.     Here is a typical application of the IGNORE command:
  1457.  
  1458.     IGNORE $FLINE[3 9] ^ "Date"
  1459.  
  1460.     This skips any input line that contains the word "Date" between columns 3
  1461.     and 9 ($FLINE is the line just read from the input file).
  1462.  
  1463.  
  1464.                                  ------------------
  1465.                                  The ACCEPT Command
  1466.                                  ------------------
  1467.  
  1468.     FORMAT:        ACCEPT value1 [comparator] value2
  1469.  
  1470.     PURPOSE:       The ACCEPT command accepts the input line if the comparison
  1471.                    is true.  value2.  ACCEPT commands can be "clustered" to
  1472.                    allow a series of related tests.
  1473.  
  1474.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1475.                    In the following explanation, we will demonstrate the
  1476.                    command using only the "literally identical" ("=")
  1477.                    comparator.
  1478.  
  1479.     ALTERNATIVES:  The IGNORE command.
  1480.  
  1481.     If the entire POM file reads as follows:
  1482.  
  1483.     ACCEPT $FLINE[15 17] = "YES"
  1484.     OUTEND "X" = "X" |{$FLINE}
  1485.  
  1486.     then any input line that contains "YES" starting in column 15 is sent to
  1487.     the output file.  All other lines are ignored.
  1488.  
  1489.  
  1490.     Clustered Accepts
  1491.     -----------------
  1492.  
  1493.     Sometimes you have to check more than one value to see if the input line is
  1494.     valid.  You do this by using "clustered ACCEPTs", which are several ACCEPT
  1495.     commands in a row.
  1496.  
  1497.     Briefly stated, if you have several ACCEPTs in a row ("clustered"), they
  1498.     are all processed to determine if the input line is acceptable or not.  If
  1499.     even one ACCEPT matches up, the line is accepted.  To express this in more
  1500.     detail...
  1501.  
  1502.     When the comparison is true, the line is accepted, and processing of the
  1503.     POM file continues for that input line, even if the immediately following
  1504.     ACCEPTs do NOT produce a match.  After all, we've already got a match!
  1505.  
  1506.     If value1 does NOT contain value2, Parse-O-Matic looks at the next commmand
  1507.     in the POM file.  If it is not another ACCEPT, the input line is ignored.
  1508.     If it is another ACCEPT, maybe it will product a match -- so Parse-O-Matic
  1509.     moves to that command.
  1510.  
  1511.     The following POM file uses clustered ACCEPTs to accept any line that
  1512.     contains the name "FRED" or "MARY" between columns 5 and 8, or contains the
  1513.     word "MEMBER" between columns 20 and 25.
  1514.  
  1515.     SET    NAME = $FLINE[5 8]         <-- Set the variable
  1516.     ACCEPT NAME = "FRED"              <-- Look for FRED
  1517.     ACCEPT NAME = "MARY"              <-- Look for MARY
  1518.     ACCEPT $FLINE[20 25] = "MEMBER"   <-- Look for MEMBER
  1519.     OUTEND "X" = "X" |{$FLINE}        <-- Output the line if we get this far
  1520.  
  1521.     The following example will NOT work, however:
  1522.  
  1523.     ACCEPT $FLINE[20 25] = "MEMBER"
  1524.     SET    NAME = $FLINE[5 8]
  1525.     ACCEPT NAME = "FRED"
  1526.     ACCEPT NAME = "MARY"
  1527.     OUTEND "X" = "X" |{$FLINE}
  1528.  
  1529.     It will not work because the ACCEPTs are not clustered; if the first ACCEPT
  1530.     fails, the input line is rejected as soon as the SET command is
  1531.     encountered.  The next two ACCEPTs are not reached in such case.
  1532.  
  1533.  
  1534.  
  1535.     ===========================================================================
  1536.                                FLOW CONTROL COMMANDS
  1537.     ===========================================================================
  1538.  
  1539.  
  1540.                                  -----------------
  1541.                                  The BEGIN Command
  1542.                                  -----------------
  1543.  
  1544.     FORMAT:        The basic format for the BEGIN command is as follows:
  1545.  
  1546.                    BEGIN value1 [comparator] value2
  1547.                    :
  1548.                    Dependant code
  1549.                    :
  1550.                    END
  1551.  
  1552.     PURPOSE:       If the comparison is true (e.g. value1 equals value2), then
  1553.                    the dependant code (the POM lines between the BEGIN and the
  1554.                    END) are executed.  If the comparison is false, then the
  1555.                    dependant code is skipped.
  1556.  
  1557.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1558.                    In the following explanation, we will demonstrate the
  1559.                    command using only the "literally identical" ("=")
  1560.                    comparator.
  1561.  
  1562.     SEE ALSO:      "The Else Command" and "The Again Command"
  1563.  
  1564.     It is traditional in programming to indent code that appears in blocks
  1565.     such as Parse-O-Matic's BEGIN/END technique.  This makes the logic of
  1566.     the POM file easier for us to understand.  For example:
  1567.  
  1568.     BEGIN datatype = "Employee"
  1569.       SET phone    = $FLINE[ 1 10]
  1570.       SET address  = $FLINE[12 31]
  1571.     END
  1572.  
  1573.     BEGIN/END blocks can be nested.  That is to say, you can have BEGIN/END
  1574.     blocks inside other BEGIN/END blocks.  Here is an example, with arrows
  1575.     to indicate the levels of each BEGIN/END block...
  1576.  
  1577.     BEGIN datatype = "Employee"      <---------------------
  1578.       SET phone    = $FLINE[ 1 10]                        |
  1579.       SET address  = $FLINE[12 31]                        |
  1580.       SET areacode = phone[1 3]                           | First
  1581.       BEGIN areacode = "514"         <------- Second      | Level
  1582.         SET local = "Y"                     | Level       | Block
  1583.         SET tax   = "Y"              <------- Block       |
  1584.       END                                                 |
  1585.     END                              <---------------------
  1586.  
  1587.     In this case, the "inner" block (starting with BEGIN areacode = "514") is
  1588.     reached only if the "outer" block (BEGIN datatype = "Employee") is true.
  1589.     If the outer block is false, the inner block is ignored.
  1590.  
  1591.     A nested BEGIN/END block must always be completely inside the outer block.
  1592.     Study the following (incorrect) example:
  1593.  
  1594.     BEGIN datatype = "Employee"             <----
  1595.       SET phone    = $FLINE[ 1 10]              |  First
  1596.       SET areacode = phone[1 3]                 |  Level
  1597.       BEGIN areacode = "514"         <---       |  Block?
  1598.         SET local = "Y"                 |       |
  1599.     END                                 |   <----
  1600.       SET tax = "Y"                     |
  1601.       END                            <---  Second Level Block?
  1602.  
  1603.     Parse-O-Matic does not pay attention to the indenting -- it is only a
  1604.     tradition we use to make the file easier to read.  The code will be
  1605.     understood this way:
  1606.  
  1607.     BEGIN datatype = "Employee"      <---------------------
  1608.       SET phone    = $FLINE[ 1 10]                        | First
  1609.       SET areacode = phone[1 3]                           | Level
  1610.       BEGIN areacode = "514"         <--- Second          | Block
  1611.         SET local = "Y"                 | Level           |
  1612.       END                            <--- Block           |
  1613.       SET tax = "Y"                                       |
  1614.     END                              <---------------------
  1615.  
  1616.     You can nest BEGIN/END blocks up to 25 deep -- although it is unlikely you
  1617.     will ever need that much nesting.  Here is an example of code that uses
  1618.     nesting up to three deep:
  1619.  
  1620.     BEGIN datatype = "Dog"           <----------------------------------
  1621.       SET breed = $FLINE[1 10]                                         | First
  1622.       BEGIN breed = "Collie"         <-----------------------          | Level
  1623.         SET noise = "Woof"                                  | Second   | Block
  1624.         BEGIN name = "Spot"          <------ Third          | Level    |
  1625.           SET attitude = "Friendly"        | Level          | Block    |
  1626.         END                          <------ Block          |          |
  1627.       END                            <-----------------------          |
  1628.       BEGIN breed = "Other"          <----------------------- Another  |
  1629.         SET noise = "Arf"                                   | Second   |
  1630.         SET attitude = "Unknown"                            | Level    |
  1631.       END                            <----------------------- Block    |
  1632.     END                              <----------------------------------
  1633.  
  1634.     Once again, the indentation is for clarity only and does not affect the
  1635.     way the POM file runs.  However, you will find that it makes your POM
  1636.     file much easier to understand.
  1637.  
  1638.  
  1639.                                   ----------------
  1640.                                   The ELSE Command
  1641.                                   ----------------
  1642.  
  1643.     FORMAT:        The format of a BEGIN/ELSE/END block is as follows:
  1644.  
  1645.                    BEGIN value1 [comparator] value2
  1646.                    :
  1647.                    Code that is run if the comparison is true
  1648.                    :
  1649.                    ELSE
  1650.                    :
  1651.                    Code that is run if the comparison is false
  1652.                    :
  1653.                    END
  1654.  
  1655.     PURPOSE:       The ELSE command tells Parse-O-Matic to execute the
  1656.                    following block of code (up until the END command) if the
  1657.                    corresponding BEGIN comparison is NOT true.
  1658.  
  1659.     NOTES:         The ELSE command is not the same as the ELSE used to pad the
  1660.                    IF statement (e.g. IF xyz = "3" THEN x = "Y" ELSE "N").  In
  1661.                    the IF command, ELSE makes the statement more clear, but it
  1662.                    can be omitted (e.g. IF $FLINE[1] "3" x "Y" "N").
  1663.  
  1664.     Here is an example of a BEGIN/ELSE/END block:
  1665.  
  1666.     BEGIN $FLINE[1 10] = "JOHN SMITH"
  1667.       SET x = "This is John"
  1668.     ELSE
  1669.       SET x = "This is not John"
  1670.     END
  1671.  
  1672.     If you are using several levels of nesting, it is a good idea to indent
  1673.     your code to show the relationship of the BEGIN, ELSE and END statements:
  1674.  
  1675.     BEGIN datatype = "Dog"           <----------------------------------
  1676.       SET breed = $FLINE[1 10]                                         | First
  1677.       BEGIN breed = "Collie"         <-----------------------          | Level
  1678.         SET noise = "Woof"                                  | Second   | Block
  1679.         BEGIN name = "Spot"          <------ Third          | Level    |
  1680.           SET attitude = "Friendly"        | Level          | Block    |
  1681.         END                          <------ Block          |          |
  1682.       ELSE                                                  |          |
  1683.         SET noise = "Arf"                                   |          |
  1684.         SET attitude = "Unknown"                            |          |
  1685.       END                            <-----------------------          |
  1686.     END                              <----------------------------------
  1687.  
  1688.     The ELSE is at "Level 2".  This is because there are three BEGINs ahead of
  1689.     it, but only one END (3 - 1 = 2).
  1690.  
  1691.  
  1692.                                   ---------------
  1693.                                   The END Command
  1694.                                   ---------------
  1695.  
  1696.     FORMAT:        END
  1697.  
  1698.     PURPOSE:       Marks the end of a BEGIN, PROLOGUE or EPILOGUE code block.
  1699.  
  1700.     The END command marks the end of a "code block".  A code block is a series
  1701.     of lines in a POM file that may be run if the conditions are right.
  1702.  
  1703.     For a more detailed discussion of the END command, see the following
  1704.     sections:
  1705.  
  1706.     - "The Begin Command"
  1707.  
  1708.     - "The Prologue Command"
  1709.  
  1710.     - "The Epilogue Command"
  1711.  
  1712.  
  1713.                                  -----------------
  1714.                                  The AGAIN Command
  1715.                                  -----------------
  1716.  
  1717.     FORMAT #1:     BEGIN [value1 [comparator] value2]
  1718.                    :
  1719.                    Code executed if the BEGIN comparison is true or omitted
  1720.                    :
  1721.                    AGAIN [value1 [comparator] value2]
  1722.  
  1723.     FORMAT #2:     BEGIN value1 [comparator] value2
  1724.                    :
  1725.                    Code executed if the BEGIN comparison is true
  1726.                    :
  1727.                    ELSE
  1728.                    :
  1729.                    Code executed if the BEGIN comparison is false
  1730.                    :
  1731.                    AGAIN [value1 [comparator] value2]
  1732.  
  1733.     PURPOSE:       Controls the repetition of a BEGIN block.
  1734.  
  1735.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1736.  
  1737.     SEE ALSO:      "The ReadNext Command", "The Begin Command", "The Else
  1738.                    Command" and "Uninitialized and Persistent Variables"
  1739.  
  1740.     DEFAULTS:      If the comparison part of the AGAIN command is omitted:
  1741.                    - AGAIN repeats if the BEGIN comparison was true or omitted
  1742.                    - AGAIN does not repeat if the BEGIN comparison was false
  1743.  
  1744.     ADVISORY:      If you are familiar with other computer languages, you may
  1745.                    be tempted to use AGAIN to create loops when none are
  1746.                    required.  Remember that a POM file is repeated (i.e.
  1747.                    looped) each time a record or line is read from the input
  1748.                    file.  The AGAIN command is most appropriate when you have
  1749.                    input records with a variable number of items.
  1750.  
  1751.     The AGAIN command allows you to implement "loops".  A loop is a section of
  1752.     code that can be repeated one or more times.
  1753.  
  1754.     AGAIN returns to the corresponding BEGIN if the comparison is true, or if
  1755.     it is omitted.  Since the BEGIN can also have a comparison, and can be used
  1756.     in conjunction with the ELSE command, this allows many variations:
  1757.  
  1758.     COMMAND ARRANGEMENT             EFFECT
  1759.     ------------------------------  -----------------------------------------
  1760.     BEGIN               AGAIN       Loops forever
  1761.     BEGIN comp          AGAIN       Loops until the BEGIN comparison is false
  1762.     BEGIN               AGAIN comp  Loops until the AGAIN comparison is false
  1763.     BEGIN comp          AGAIN comp  Loops until either comparison is false
  1764.     BEGIN comp   ELSE   AGAIN comp  Loops until either comparison is false
  1765.     BEGIN comp   ELSE   AGAIN       Loops until the BEGIN comparison is false
  1766.  
  1767.     In the last two examples, the ELSE code is run when the BEGIN comparison is
  1768.     false, then processing continues on the POM line after the AGAIN command.
  1769.     When a BEGIN comparison is false, the comparison (if any) of the AGAIN
  1770.     command is not evaluated.
  1771.  
  1772.     To put it another way:  the AGAIN comparison is considered only if the
  1773.     BEGIN comparison is true or omitted.
  1774.  
  1775.  
  1776.     Using AGAIN for Variable-Length Data
  1777.     ------------------------------------
  1778.  
  1779.     Let us say you have a text file that contains the names of people belonging
  1780.     to various clubs.  The file lists the name of the club, then the number of
  1781.     people in each club, and then the names:
  1782.  
  1783.     Chess Club
  1784.     3
  1785.     John Smith
  1786.     Mary Jones
  1787.     Fred Williams
  1788.     Hopscotch Club
  1789.     0
  1790.     Tennis Club
  1791.     2
  1792.     Jack Martin
  1793.     Debbie Harris
  1794.  
  1795.     You could process this input file with the following POM file:
  1796.  
  1797.     PAD      $FLINE "R" " " "17"      <-- Pad the club name out with spaces
  1798.     OUT      |{$FLINE}                <-- Send the club name to the output file
  1799.     READNEXT                          <-- Get the number of members
  1800.     SET      members  = $FLINE        <-- Remember this number
  1801.     BEGIN    members  = "0"           <-- Check if we have any members
  1802.       OUT      |(None)                <-- Report if we have no members
  1803.     ELSE                              <-- If we have members, do the next part
  1804.       SET      count    = "0"         <-- Initialize a counter
  1805.       BEGIN                           <-- Start the loop
  1806.         READNEXT                      <-- Get the person's name
  1807.         SET    count = count+         <-- Count this person
  1808.         OUT    |{$FLINE}              <-- Send the name to the file
  1809.         OUT    count #< members |/    <-- Add a separator if not the last name
  1810.       AGAIN    count #< members       <-- Go back if we have more members
  1811.     END                               <-- Corresponds to the first BEGIN
  1812.     OUTEND  |                         <-- Start a new line after each club
  1813.  
  1814.     This POM file would generate the following output:
  1815.  
  1816.     Chess Club       John Smith/Mary Jones/Fred Williams
  1817.     Hopscotch Club   (None)
  1818.     Tennis Club      Jack Martin/Debbie Harris
  1819.  
  1820.  
  1821.     Pointless Command Combinations
  1822.     ------------------------------
  1823.  
  1824.     Some combinations of BEGIN, ELSE and AGAIN are pointless.  The following
  1825.     command arrangements contain code that is never run:
  1826.  
  1827.     COMMAND ARRANGEMENT             NOTE
  1828.     ------------------------------  ------------------------------------------
  1829.     BEGIN        ELSE   AGAIN comp  The ELSE portion is never executed
  1830.     BEGIN        ELSE   AGAIN       Loops forever; the ELSE portion never runs
  1831.  
  1832.  
  1833.     Examples
  1834.     --------
  1835.  
  1836.     Either of these two POM files will read a text file and ignore any lines
  1837.     that contain the words "COW":
  1838.  
  1839.     Using the AGAIN Command       Using the IGNORE Command
  1840.     -----------------------       ------------------------
  1841.     BEGIN $FLINE ^ "COW"          IGNORE $FLINE ^ "COW"
  1842.       READNEXT                    OUTEND |{$FLINE}
  1843.     AGAIN
  1844.     OUTEND |{$FLINE}
  1845.  
  1846.     The shorter POM file is more efficient, but the results would be the
  1847.     roughly the same for both.  Remember that a POM file is processed each
  1848.     time Parse-O-Matic reads an input record (or line), so the second version
  1849.     is, in effect, looping as many times as there are records in the file.
  1850.  
  1851.     The following POM file will read one line from a file, then send the string
  1852.     [6]123[7]123[6]123[7]123 to the output file:
  1853.  
  1854.     SET      z = "0"
  1855.     BEGIN                      <-----------------------------
  1856.       SET      y = "5"                                      | First
  1857.       BEGIN    y <> "7"        <------------------          | Level
  1858.         SET      x = "0"                         | Second   | (Outermost)
  1859.         SET      y = y+                          | Level    | Loop
  1860.         APPEND   s s "[" y "]"                   | Loop     |
  1861.         BEGIN    x <> "3"      <--------         |          |
  1862.           SET      x = x+              | Third   |          |
  1863.           APPEND   s s x               | Level   |          |
  1864.         AGAIN                  <--------         |          |
  1865.       AGAIN                    <------------------          |
  1866.       SET     z = z+                                        |
  1867.     AGAIN   z <> "2"           <-----------------------------
  1868.     OUTEND  |{s}
  1869.     NEXTFILE
  1870.  
  1871.     The third level (innermost) loop ... generates 123
  1872.     The second level (middle) loop ..... generates [6]123[7]123
  1873.     The first level (outermost) loop ... generates [6]123[7]123[6]123[7]123
  1874.  
  1875.     The following POM file will read one line from a file, then send the
  1876.     string "XXXY" to the output file:
  1877.  
  1878.     SET      z = "0"           <-- Initialize a counter
  1879.     SET      s = ""            <-- Initialize the string we will output
  1880.     BEGIN    z < "3"           <-- Check if the counter has reached "3"
  1881.       SET      z = z+          <-- Add one to the counter
  1882.       APPEND   s s "X"         <-- Add an "X" to the end of the output string
  1883.     ELSE                       /__ The ELSE section is run when
  1884.       APPEND   s s "Y"         \   the BEGIN comparison is false
  1885.     AGAIN                      <-- Go back to the BEGIN
  1886.     OUTEND   |{s}              <-- Continue here after the ELSE portion
  1887.     NEXTFILE                   <-- Stop reading the input file
  1888.  
  1889.  
  1890.                                   ----------------
  1891.                                   The DONE Command
  1892.                                   ----------------
  1893.  
  1894.     FORMAT:        DONE [value1 [comparator] value2]
  1895.  
  1896.     PURPOSE:       The DONE command will discontinue processing the POM file
  1897.                    and proceed to the next input line, whereupon the POM file
  1898.                    will restart at the top.
  1899.                                  
  1900.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1901.                    In the following explanation, we will demonstrate the
  1902.                    command using only the "literally identical" ("=")
  1903.                    comparator.
  1904.  
  1905.     ALTERNATIVES:  The NEXTFILE, IGNORE and ACCEPT commands.
  1906.  
  1907.     The DONE command is most useful when you have a long series of BEGIN/END
  1908.     blocks which make a related comparison.  For example:
  1909.  
  1910.     SET   salesrep = $FLINE[11 50]
  1911.     SET   region   = $FLINE[ 1  2]
  1912.     BEGIN region = "US"
  1913.       OUTEND |Sales representative for U.S.A.: {salesrep}
  1914.       DONE
  1915.     END
  1916.     BEGIN region = "CN"
  1917.       OUTEND |Sales representative for Canada: {salesrep}
  1918.       DONE
  1919.     END
  1920.     BEGIN region = "EU"
  1921.       OUTEND |Sales representative for Europe: {salesrep}
  1922.       DONE
  1923.     END
  1924.     :
  1925.     etc.
  1926.  
  1927.     As you can see, if one of the BEGIN comparisons is true, all of the
  1928.     following ones will inevitably be false.  Rather than processing all the
  1929.     others, you can use the DONE command to bail out and get ready for the
  1930.     next input line.
  1931.  
  1932.     The DONE command provides two benefits:
  1933.  
  1934.     - It can speed up processing slightly
  1935.     - It makes full traces easier to understand
  1936.  
  1937.     For an explanation of traces, see the section entitled "Tracing".
  1938.  
  1939.     Unless you use a comparison (explained later), the DONE command is useful
  1940.     only inside BEGIN/ELSE/END blocks.  If you write a POM file like this:
  1941.  
  1942.     SET custnum  = $FLINE[ 1 10]
  1943.     SET custname = $FLINE[11 50]
  1944.     DONE
  1945.     OUTEND |{custname} {custnum}
  1946.  
  1947.     then the OUTEND statement will NEVER be reached.
  1948.  
  1949.     Here is how you specify a comparison for the DONE command:
  1950.  
  1951.     DONE $FLINE = "End of Data"
  1952.  
  1953.     This discontinues the POM file, and proceeds to the next input line, if the
  1954.     current input line ($FLINE) is "End of Data".
  1955.  
  1956.  
  1957.                                 --------------------
  1958.                                 The NEXTFILE Command
  1959.                                 --------------------
  1960.  
  1961.     FORMAT:        NEXTFILE [value [comparator] value]
  1962.  
  1963.     PURPOSE:       NEXTFILE discontinues processing the current input file and
  1964.                    proceeds to the next one, restarting the POM file from the
  1965.                    top.
  1966.  
  1967.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1968.                    In the following explanation, we will demonstrate the
  1969.                    command using only the "literally identical" ("=")
  1970.                    comparator.
  1971.  
  1972.     ALTERNATIVES:  The HALT command.
  1973.  
  1974.     The NEXTFILE command is useful when you process multiple input files (see
  1975.     "POM and Wildcards").  Here is an example, which we will call TEST.POM:
  1976.  
  1977.     BEGIN $FLINE = "End of Data"
  1978.       OUTEND |{numlines} lines of data printed
  1979.       SET    numlines = ""
  1980.       NEXTFILE
  1981.     END
  1982.     SET    numlines = numlines+
  1983.     OUTEND |{$FLINE}
  1984.  
  1985.     Let's say you have three text files: DATA1.XYZ, DATA2.XYZ and DATA3.XYZ.
  1986.     The last line of each file says "End of Data".  You could copy all three
  1987.     files to the file OUTPUT.TXT with this command:
  1988.  
  1989.     POM TEST.POM DATA?.XYZ OUTPUT.TXT
  1990.  
  1991.     This would copy the data from each file, but when it gets to the line
  1992.     reading "End of Data", it records the number of lines of data that were
  1993.     printed.  Any lines after the "End of Data" line are skipped, because of
  1994.     the NEXTFILE command.
  1995.  
  1996.     The NEXTFILE command can specify a comparison.  Here is an example:
  1997.  
  1998.     NEXTFILE $FLINE = "End of Data"
  1999.     OUTEND |{$FLINE}
  2000.  
  2001.     Assuming the same input files (DATA1.XYZ etc.), and using the same POM
  2002.     command as last time, this POM file would simply copy up to (but not
  2003.     including" the line that reads "End of Data" in each input file.
  2004.  
  2005.  
  2006.                                   ----------------
  2007.                                   The HALT Command
  2008.                                   ----------------
  2009.  
  2010.     FORMAT:        HALT value1 comparison value2 value3 [value4]
  2011.  
  2012.     PURPOSE:       The HALT command will terminate Parse-O-Matic processing if
  2013.                    the comparison is true.
  2014.  
  2015.     PARAMETERS:    value1 is any value
  2016.                    value2 is any value
  2017.                    value3 is the message to be displayed
  2018.                    value4 is the optional error level (between 100 to 199)
  2019.  
  2020.     NUMERICS:      Tabs, spaces and commas are stripped from value4
  2021.  
  2022.     ALTERNATIVES:  The NEXTFILE command.
  2023.  
  2024.     SEE ALSO:      "The MsgWait Command"
  2025.  
  2026.     Here is an example of the HALT command:
  2027.  
  2028.     HALT sales = "0" "Zero sales!"
  2029.  
  2030.     If the variable named sales is "0", Parse-O-Matic will display an error
  2031.     box reading "Zero sales!" and terminate after you've pressed a key.  A copy
  2032.     of the message is also placed in the processing log POMLOG.TXT (see
  2033.     "Logging").
  2034.  
  2035.     When a HALT condition occurs, Parse-O-Matic terminates with a DOS error
  2036.     level of 100.  You can specify a different value, using value4.  This is
  2037.     useful if you are calling Parse-O-Matic from a batch file or application
  2038.     program and want to handle different errors in different ways.
  2039.  
  2040.     You can set value4 to any number between 100 and 199.  Consider these
  2041.     examples:
  2042.  
  2043.     HALT sales    = "0" "Zero sales"     "150"
  2044.     HALT sales[1] = "-" "Negative sales" "160"
  2045.  
  2046.     This terminates Parse-O-Matic with an error level of 150 if sales are zero.
  2047.     If the first character of sales is a minus sign, Parse-O-Matic terminates
  2048.     with an error level of 160.
  2049.  
  2050.     When coding batch files, remember that the IF ERRORLEVEL command is
  2051.     considered "True" if the error is the specified value or higher.  This
  2052.     means you should always test the higher value first.  See your DOS manual
  2053.     for details.
  2054.  
  2055.  
  2056.                                 --------------------
  2057.                                 The PROLOGUE Command
  2058.                                 --------------------
  2059.  
  2060.     FORMAT:        The format for PROLOGUE (used in conjunction with the END
  2061.                    command) is as follows:
  2062.  
  2063.                    PROLOGUE
  2064.                    :
  2065.                    Dependant code
  2066.                    :
  2067.                    END
  2068.  
  2069.     PURPOSE:       PROLOGUE defines dependant code which is run before the
  2070.                    first line of the input file is read.
  2071.  
  2072.     SEE ALSO:      "The Epilogue Command"
  2073.  
  2074.     PROLOGUE can be used to set up some variables, or set up a heading --
  2075.     anything you only want to do once per input file, at the very start.
  2076.  
  2077.     Here is an example of the PROLOGUE command:
  2078.  
  2079.     PROLOGUE
  2080.       SET both  = "B"
  2081.       SET space = " "
  2082.     END
  2083.     SET    firstname = $FLINE[ 1 10]
  2084.     SET    lastname  = $FLINE[15 25]
  2085.     TRIM   firstname both space
  2086.     TRIM   lastname  both space
  2087.     OUTEND |{firstname} {lastname}
  2088.  
  2089.     When the input file is first opened, the PROLOGUE section sets the
  2090.     variables "both" and "space".  Once they're set, you don't have to change
  2091.     them (since you're just using them to make the code easier to read).  Thus,
  2092.     it makes sense to set them only at the beginning of processing and not
  2093.     bother setting them each time the POM file is executed (i.e. each time an
  2094.     input line is read).
  2095.  
  2096.     If you are working with multiple files (see "POM and Wildcards"), the
  2097.     PROLOGUE is run for each input file.  If you want to run some code for
  2098.     the first file only, you can set a "flag", as in this example:
  2099.  
  2100.     BEGIN firstfile = ""
  2101.       SET firstfile = "N"
  2102.       OUTEND |First file only
  2103.     ELSE
  2104.       OUTEND |Subsequent files
  2105.     END
  2106.     NEXTFILE
  2107.  
  2108.     If you run this POM file on several files at once, using wildcards, the
  2109.     first line of the output file will contain the words "First file only",
  2110.     since the variable "firstfile" has not yet been assigned a value.  On
  2111.     subsequent files, the variable will have the value "N", so the following
  2112.     lines of the output file will read "Subsequent files".
  2113.  
  2114.  
  2115.                                 --------------------
  2116.                                 The EPILOGUE Command
  2117.                                 --------------------
  2118.  
  2119.     FORMAT:        The format for EPILOGUE (used in conjunction with the END
  2120.                    command) is as follows:
  2121.  
  2122.                    EPILOGUE
  2123.                    :
  2124.                    Dependant code
  2125.                    :
  2126.                    END
  2127.  
  2128.     PURPOSE:       EPILOGUE defines dependant code which is run after the last
  2129.                    line of the input file is read and the POM file is executed
  2130.                    to process it.  In other words, once all the input data is
  2131.                    finished, the POM file runs one last time -- but only the
  2132.                    code in the EPILOGUE section.
  2133.  
  2134.     SEE ALSO:      "The Prologue Command"
  2135.  
  2136.     You can use EPILOGUE to output final results.  Let's say your input file
  2137.     looks like this:
  2138.  
  2139.     DESCRIPTION      UNITS SOLD    UNIT PRICE
  2140.     Wildebeest food         325    $     9.99
  2141.     Horse cologne            13    $     3.25
  2142.     Moose alarm             210    $     5.95
  2143.     :                :        :     :       :    (Column positions)
  2144.     1               18       27    33      41
  2145.  
  2146.     You can find out the total number of units sold (of all types) with the
  2147.     following POM file:
  2148.  
  2149.     IGNORE $FLINE[1 7] = "DESCRIP"
  2150.     CALC   units = units "+" $FLINE[18 27]
  2151.     EPILOGUE
  2152.       OUTEND |Total units sold = {units}
  2153.     END
  2154.  
  2155.     This POM file adds up the number of units sold.  The only output is the
  2156.     single line generated by the OUTEND in the EPILOGUE.
  2157.  
  2158.     If you are processing multiple files (see "POM and Wildcards"), the
  2159.     EPILOGUE is run after each input file is finished.
  2160.  
  2161.  
  2162.     ===========================================================================
  2163.                                  VARIABLE MODIFIERS
  2164.     ===========================================================================
  2165.  
  2166.  
  2167.                                   ----------------
  2168.                                   The TRIM Command
  2169.                                   ----------------
  2170.  
  2171.     FORMAT:        TRIM var1 value1 value2
  2172.  
  2173.     PURPOSE:       TRIM removes the character in value2 from var1.
  2174.  
  2175.     PARAMETERS:    var1   is the variable being set
  2176.                    value1 is "A" = All; "B" = Both ends;
  2177.                              "L" = Left side only; "R" = Right side only
  2178.                    value2 is the character to be removed.
  2179.  
  2180.     ALTERNATIVES:  The CHANGE command.
  2181.  
  2182.     TRIM is usually used to remove blanks from either side of text, or leading
  2183.     zeros from numeric data.
  2184.  
  2185.     For example:
  2186.  
  2187.     SET  PRICE = $FLINE[20 26]
  2188.     TRIM PRICE "A" ","
  2189.     TRIM PRICE "L" "$"
  2190.  
  2191.     This removes all commas from the variable "PRICE", and removes the leading
  2192.     dollar sign.  Thus:
  2193.  
  2194.     If the input contains the string:   "$25,783"
  2195.     The first TRIM changes it to:       "$25783"
  2196.     The second TRIM changes it to:      "25783"
  2197.  
  2198.  
  2199.                                   ---------------
  2200.                                   The PAD Command
  2201.                                   ---------------
  2202.  
  2203.     FORMAT:        PAD var1 value1 value2 value3
  2204.                        :    :       :     :
  2205.     MEANING:       Variable Control Char  Number
  2206.  
  2207.     PURPOSE:       PAD makes var1 a specified length, padded with a
  2208.                    specified character.
  2209.  
  2210.     PARAMETERS:    var1   is the variable being set
  2211.                    value1 is "L", "R", or "C" (Left, Right or Center)
  2212.                    value2 is the character used to pad the string
  2213.                    value3 is the desired string length
  2214.  
  2215.     NUMERICS:      Tabs, spaces and commas are stripped from value3
  2216.  
  2217.     ALTERNATIVES:  The CHANGE command.
  2218.  
  2219.     Here is an example of the PAD command.  If the variable ABC is already set
  2220.     to "1234" ...
  2221.  
  2222.     PAD ABC "L" "0" "7"   left-pads it 7 characters wide with zeros ("0001234")
  2223.     PAD ABC "R" " " "5"   right-pads it 5 characters wide with spaces ("1234 ")
  2224.     PAD ABC "C" "*" "8"   centers it, 8 wide, with asterisks ("**1234**")
  2225.  
  2226.     If the length is less than the length of the string, it is unchanged.  For
  2227.     example, if you set variable XYZ to "PINNACLE", then
  2228.  
  2229.     PAD XYZ "R" " " "3"
  2230.  
  2231.     leaves the string as-is ("PINNACLE").
  2232.  
  2233.     Thus, PAD can not be used to shorten a string.  If it is your intention to
  2234.     make XYZ 3 letters long, you can use the SET command:
  2235.  
  2236.     SET XYZ = XYZ[1 3]
  2237.  
  2238.  
  2239.                                  ------------------
  2240.                                  The CHANGE Command
  2241.                                  ------------------
  2242.  
  2243.     FORMAT:        CHANGE var1 value1 value2
  2244.  
  2245.     PURPOSE:       The CHANGE command replaces ALL occurrences of value1
  2246.                    with value2.
  2247.  
  2248.     ALTERNATIVES:  The TRIM command.  (The CHANGE command is more powerful than
  2249.                    TRIM, but is not as efficient).
  2250.  
  2251.     Here is an example of the CHANGE command in action:
  2252.  
  2253.     SET    DATE = $FLINE[31 38]
  2254.     CHANGE DATE "/" "--"
  2255.  
  2256.     If the SET command assigns DATE the value:    "93/10/15"
  2257.     Then the CHANGE command converts it to:       "93--10--15"
  2258.  
  2259.  
  2260.                                 -------------------
  2261.                                 The CVTCASE Command
  2262.                                 -------------------
  2263.  
  2264.     FORMAT:        CVTCASE  var1 value1 [value2]
  2265.  
  2266.     PURPOSE:       CVTCASE converts a value to uppercase or lowercase.
  2267.  
  2268.     PARAMETERS:    var1   is the variable being set
  2269.                    value1 is the value being converted
  2270.                    value2 is the optional control setting
  2271.  
  2272.     DEFAULTS:      value2 = "UI"
  2273.  
  2274.     ALTERNATIVES:  The PROPER or REMAP commands; $FLUPC
  2275.  
  2276.     CVTCASE converts value1 to uppercase or lowercase and places the result in
  2277.     var1.  Here are some examples:
  2278.  
  2279.          COMMAND                      DESCRIPTION
  2280.          ---------------------------  --------------------------------
  2281.          CVTCASE xyz "Test Case" "U"  Sets variable xyz to "TEST CASE"
  2282.          CVTCASE xyz "Test Case" "L"  Sets variable xyz to "test case"
  2283.          CVTCASE xyz "Test Case"      Sets variable xyz to "TEST CASE"
  2284.  
  2285.     In the last example, the optional control parameter (value2) was omitted.
  2286.     In such case, CVTCASE will convert the value to uppercase.
  2287.  
  2288.  
  2289.     Control Settings
  2290.     ----------------
  2291.  
  2292.     The control setting (value2) can be one or two characters long, or it can
  2293.     be omitted (in which case it is assumed to be "UI").  Here are the
  2294.     available settings for value2:
  2295.  
  2296.                     SETTING  CONVERT TO  CHARACTER SET
  2297.                     -------  ----------  ------------------
  2298.                     "L"      Lowercase   IBM Extended ASCII
  2299.                     "LI"     Lowercase   IBM Extended ASCII
  2300.                     "L7"     Lowercase   7-bit ASCII
  2301.                     "U"      Uppercase   IBM Extended ASCII
  2302.                     "UI"     Uppercase   IBM Extended ASCII
  2303.                     "U7"     Uppercase   7-bit ASCII
  2304.  
  2305.     The IBM Extended ASCII character set defines diacritical (accented)
  2306.     characters such as "U Umlaut" and "C Cedille"; these are located in the
  2307.     ASCII table above value 127.  It is the standard character set used by
  2308.     MS-DOS and PC-DOS.
  2309.  
  2310.     The 7-bit ASCII character set is concerned only with the characters in the
  2311.     original definition of ASCII (American Standard Code for Information
  2312.     Interchange), which does not support diacritical characters.  As such,
  2313.     uppercasing and lowercasing affect only alphabetic characters ("A" to "Z",
  2314.     and "a" to "z").  This character set is used by many mini-computers, and
  2315.     is the standard character set of the Unix operating system.
  2316.  
  2317.     The eighth bit is not ignored if you use CVTCASE with the 7-bit ASCII
  2318.     character set.  If you wish to set the eighth bit to zero (perhaps because
  2319.     it is a parity bit), you should use the REMAP command.
  2320.  
  2321.  
  2322.                                  ------------------
  2323.                                  The PROPER Command
  2324.                                  ------------------
  2325.  
  2326.     FORMAT:        PROPER var1 [value1 [value2]]
  2327.  
  2328.     PURPOSE:       The PROPER command converts uppercase text (LIKE THIS) to
  2329.                    mixed-case text (Like This).
  2330.  
  2331.     PARAMETERS:    var1   is the variable being set
  2332.                    value1 is the methods setting
  2333.                    value2 is the name of the Properization Exception File
  2334.  
  2335.     DEFAULTS:      value1 = "IW"
  2336.  
  2337.     ALTERNATIVES:  The CHANGE command; $FLUPC (uppercase version of $FLINE).
  2338.  
  2339.     The PROPER command is useful when you have a list of names of people and
  2340.     addresses.  You can also use PROPER to change text that has been typed in
  2341.     uppercase into normal text, with capital letters at the beginning of
  2342.     sentences.
  2343.  
  2344.     The simplest way to convert a variable is as follows:
  2345.  
  2346.     PROPER CustName
  2347.  
  2348.     If CustName contains "JOHN SMITH", it will be changed to "John Smith".
  2349.  
  2350.     The conversion routine is fairly intelligent.  For example, if it is
  2351.     converting the words "JAGUAR XJS", it can tell that XJS is not a word
  2352.     (since it does not contain any vowels) and so the the end result will
  2353.     be "Jaguar XJS".  Other "strange-looking" items such as serial numbers
  2354.     can often be recognized by the PROPER command, and left untouched.
  2355.  
  2356.     Nevertheless, it is impossible to handle all situations, so the PROPER
  2357.     command supports a "Properization Exceptions File" (known as a PEF file).
  2358.     A PEF file lists unusual combinations of letters (typically abbreviations,
  2359.     such as Dr.).  The Parse-O-Matic package includes a file named GENERIC.PEF,
  2360.     which you may find helpful.  You can view it with the SEE program provided
  2361.     with Parse-O-Matic.
  2362.  
  2363.     A PEF file is prepared with a text editor and contains one "exception" per
  2364.     line.  Null or blank lines, or lines that start with a semicolon, are
  2365.     ignored.  The longest word that can be specified is 255 characters.
  2366.     Spaces are permitted, but leading and trailing spaces and tabs are ignored.
  2367.  
  2368.     To use the PEF file in your PROPER command, place the file name after the
  2369.     variable name and method setting.  For example:
  2370.  
  2371.     PROPER CustName "W" "GENERIC.PEF"
  2372.  
  2373.     The "W" is the method setting (explained later).  "GENERIC.PEF" is the name
  2374.     of the PEF file.  When Parse-O-Matic looks for the PEF file, it looks for
  2375.     it in the current directory unless an explicit path is specified, then
  2376.     searches elsewhere, if necessary.  (For details, see the section entitled
  2377.     "How Parse-O-Matic Searches for a File".)
  2378.  
  2379.     If it can not find it there, it looks in the
  2380.     directory where POM.EXE is located.  You can, if you wish, specify a
  2381.     complete path to the file, as in this example:
  2382.  
  2383.     PROPER Address "W" "C:\MYFILES\MYPEF.XYZ"
  2384.  
  2385.     If you don't need an exceptions file, you should not use it, since it slows
  2386.     down processing somewhat.  Needless to say, the more items you have in the
  2387.     PEF file, the more it slows down processing.
  2388.  
  2389.     The method setting allows you to specify what PROPER does.  There are
  2390.     several kinds of controls, as follows:
  2391.  
  2392.           METHOD   DESCRIPTION
  2393.           ------   -----------
  2394.             I      Intelligent determination of non-words
  2395.             S      Upcase the first character of each sentence
  2396.             U      Upcase the first alphanumeric character of the line
  2397.             W      Upcase the first letter of each word
  2398.  
  2399.     The default method setting is "IW", so if you omit the method setting, or
  2400.     specify a null setting (e.g. PROPER CustName "" "XYZ.PEF"), PROPER will
  2401.     upcase non-words, and the first letter of each word.
  2402.  
  2403.     NOTE:  If you specify a PEF file, you must also specify a method setting,
  2404.     even if it is null.  The line PROPER "GENERIC.PEF" would not be understood
  2405.     by Parse-O-Matic.  The correct format would be:  PROPER "" "GENERIC.PEF"
  2406.  
  2407.     The examples provided with Parse-O-Matic demonstrate some ways you can use
  2408.     the PROPER command.  To see the examples, enter START at the DOS prompt,
  2409.     or run START.BAT from Windows or OS/2, then select TUTORIAL.
  2410.  
  2411.  
  2412.                                  ------------------
  2413.                                  The INSERT Command
  2414.                                  ------------------
  2415.  
  2416.     FORMAT:        INSERT var1 value1 value2
  2417.  
  2418.     PURPOSE:       The INSERT command inserts text on the left or right of
  2419.                    var1, or at a "found text" position.
  2420.  
  2421.     PARAMETERS:    var1   is the variable being set
  2422.                    value1 is "L" or "R" (Left or Right) or a find-string
  2423.                           (e.g.  "<HELLO")
  2424.                    value2 is the value to be inserted
  2425.  
  2426.     ALTERNATIVES:  The APPEND and CHANGE commands.
  2427.  
  2428.     For example, if the variable ABC is set to "Parse-O-Matic", then
  2429.  
  2430.     INSERT ABC "L" "Register "    sets ABC to "Register Parse-O-Matic"
  2431.     INSERT ABC "R" " is super"    sets ABC to "Parse-O-Matic is super"
  2432.  
  2433.     You can use a find-string to insert text either before or after the first
  2434.     occurrence of the text you specify.  For example, if the variable xyz is
  2435.     set to "One a day", then
  2436.  
  2437.     INSERT xyz "<e"    "c"        sets xyz to "Once a day"
  2438.     INSERT xyz ">One " "hour "    sets xyz to "One hour a day"
  2439.  
  2440.     The < prefix means "insert value1 before the found text".  The > prefix
  2441.     means "insert value1 after the found text".
  2442.  
  2443.     If the find-string is not found, nothing is done.
  2444.  
  2445.     NOTE:  Prior to version 3.40 of Parse-O-Matic, the "insert before" opera-
  2446.            tion was denoted by the @ prefix rather than the < prefix.  This
  2447.            still works, so you do not have to change your POM files.
  2448.  
  2449.  
  2450.                                  ------------------
  2451.                                  The APPEND Command
  2452.                                  ------------------
  2453.  
  2454.     FORMAT:        APPEND var1 value1 value2 [value3 [value4]]
  2455.  
  2456.     PURPOSE:       The APPEND command concatenates (adds together) two or more
  2457.                    values and places the result in var1.
  2458.  
  2459.     NOTES:         No variable can hold more than 255 characters.
  2460.  
  2461.     ALTERNATIVES:  The INSERT command.
  2462.  
  2463.     Here is an example of the APPEND command:
  2464.  
  2465.     APPEND xyz "AB" "CD" "EF" "GHIJ"
  2466.  
  2467.     This command sets the variable xyz to "ABCDEFGHIJ".
  2468.  
  2469.     The third and fourth values (value3 and value4 in the FORMAT shown above)
  2470.     are optional.  Thus, you can use APPEND with only two values.  For example:
  2471.  
  2472.     SET    x1 = "AB"
  2473.     SET    x2 = "CD"
  2474.     APPEND x3 x1 x2
  2475.  
  2476.     This sets the variable x3 to "ABCD".  You can concatenate a maximum of four
  2477.     values with a single APPEND command.  If you require additional concaten-
  2478.     ations, you can use more APPEND commands:
  2479.  
  2480.     APPEND myvar "ABC" "DEF" "GHI" "JKL"
  2481.     APPEND myvar myvar "MNO" "PQR"
  2482.  
  2483.     The first line sets the variable myvar to "ABCDEFGHIJKL".  The second line
  2484.     set myvar to its previous value, plus "MNOPQR", so that its final value is
  2485.     "ABCDEFGHIJKLMNOPQR".
  2486.  
  2487.                                 -------------------
  2488.                                 The MAPFILE Command
  2489.                                 -------------------
  2490.  
  2491.     FORMAT:        value1 value2 [value3]
  2492.  
  2493.     PURPOSE:       MAPFILE reads a file containing data for the REMAP command
  2494.  
  2495.     PARAMETERS:    value1 is the name of the map file
  2496.                    value2 is the map name, used by the REMAP command
  2497.                    value3 is the control settings (AnyCase/MatchCase/Transpose)
  2498.  
  2499.     DEFAULTS:      value3 = "MATCHCASE"
  2500.  
  2501.     NOTES:         The maximum length of a map name is 12 characters
  2502.  
  2503.     SEE ALSO:      "The Remap Command", "How Parse-O-Matic Searches for a File"
  2504.  
  2505.     The MAPFILE command reads in a file which contains data for the REMAP
  2506.     command, and assigns a name to the collection of data so the REMAP command
  2507.     can refer to it.
  2508.  
  2509.  
  2510.     What is a Map File?
  2511.     -------------------
  2512.  
  2513.     A map file is an ordinary text file; you can create or edit the file with a
  2514.     standard text editor, or a word-processor in "generic text" mode. Map files
  2515.     are usually given the .MPF extension.
  2516.     
  2517.     A map file contains a list of "mappings".  Here are some other words with
  2518.     approximately the same meaning as "mapping":
  2519.  
  2520.       Translation   Correlation   Substitution   Equivalence   Replacement
  2521.  
  2522.     In other words, the map file contains a list of data items that should be
  2523.     replaced by other data items.
  2524.  
  2525.  
  2526.     Sample Map Files
  2527.     ----------------
  2528.  
  2529.     The following map files are included in the standard Parse-O-Matic package:
  2530.  
  2531.     FILE NAME     DESCRIPTION
  2532.     ------------  ----------------------------------------------------------
  2533.     BIN2CHAR.MPF  Converts binary data into printable characters and periods
  2534.     BIN2CODE.MPF  Converts binary data into hex codes (e.g. 3F 2C A3)
  2535.     ASC2EBCD.MPF  Converts ASCII data to EBCDIC and vice-versa
  2536.  
  2537.  
  2538.     Map File Format
  2539.     ---------------
  2540.  
  2541.     The map file contains one mapping per line.  Each mapping consists of two
  2542.     Parse-O-Matic literals, separated by one or more spaces or tabs. The first
  2543.     value is the "find" column, while the second value is the "replace" column.
  2544.     Here are some examples:
  2545.  
  2546.     "123"  "LOS ANGELES"      <-- Both values are "literal text strings"
  2547.     $39    "9"                <-- A hex code and a literal text string
  2548.     #48    "Zero"             <-- A decimal code and a literal text string
  2549.     $FF$30 #00#00             <-- Hex and decimal literals
  2550.  
  2551.     These columns are lined up for clarity; there is no need to start in a
  2552.     particular column.  Any leading or trailing spaces are removed from a
  2553.     line, and any number of spaces or tabs can appear between the columns.
  2554.  
  2555.     The following line is NOT valid:
  2556.  
  2557.     123    LOS ANGELES
  2558.  
  2559.     The line must use text, hex or decimal literals (e.g. "text", $FF, #FF).
  2560.  
  2561.     Null or blank lines, or lines that start with a semicolon, are ignored.
  2562.     The longest line that can be specified is 255 characters.  The longest
  2563.     value that can be specified is 80 characters (after translation, if it
  2564.     is in hex or decimal mode).
  2565.  
  2566.  
  2567.     Search Order
  2568.     ------------
  2569.  
  2570.     The REMAP command performs substitutions in the order that they appear in
  2571.     the map file.  In most cases, the longer "find" strings should appear
  2572.     first.  For example, let us say you create a map file named FORWARD.MPF,
  2573.     which looks like this:
  2574.  
  2575.     "123"   "in Los Angeles"
  2576.     "12"    "in Montreal"
  2577.     "1"     "in Town of Mount Royal"
  2578.     "2"     "in Podunk"
  2579.  
  2580.     Now let's say you run the following POM file, named FORWARD.POM:
  2581.  
  2582.     MAPFILE "FORWARD"
  2583.     SET     comment = "Forward the memo to office 123"
  2584.     REMAP   comment
  2585.     OUTEND  |{comment}
  2586.  
  2587.     This will produce the following output:
  2588.  
  2589.     Forward the memo to office in Los Angeles
  2590.  
  2591.     This happens because the string "123" is replaced by the string "in Los
  2592.     Angeles".
  2593.  
  2594.     If the order of the lines in FORWARD.MPF are reversed, FORWARD.POM will
  2595.     produce the following output:
  2596.  
  2597.     Forward memo to Office in Town of Mount RoyalinPodunk3
  2598.  
  2599.     This happens because the "1" is found (and replaced) first, followed by the
  2600.     "2".  Since there is no "3" in FORWARD.MPF, it is left alone.
  2601.  
  2602.     Parse-O-Matic does NOT enforce the principle of "progressively shorter
  2603.     'find' strings".  If you are processing a lot of data, you can improve
  2604.     processing speed slightly by placing a short, frequently-used "find" string
  2605.     near the top of the list.  As long as it is not a sub-string of (i.e.
  2606.     contained within) one of the following strings, it will not cause any
  2607.     problems.
  2608.  
  2609.  
  2610.     Case Matching
  2611.     -------------
  2612.  
  2613.     You can set value3 to "AnyCase" or "MatchCase" (the default).
  2614.  
  2615.     ANYCASE:    The find string need not match in case ("John" = "JOHN")
  2616.     MATCHCASE:  The find string must match ("John" does not match "JOHN")
  2617.  
  2618.     Processing is faster if you use the default setting (MatchCase).
  2619.  
  2620.  
  2621.     Reverse Mapping
  2622.     ---------------
  2623.  
  2624.     If you want the mapping process to work "backwards", you can use the
  2625.     "Transpose" control setting in value3.  For example:
  2626.  
  2627.     MAPFILE "MYFILE.MPF" "MYFILE" "AnyCase Transpose"
  2628.  
  2629.     This reverses the mapping process:  the "find" column is treated like the
  2630.     "replace with" column, and vice-versa.
  2631.  
  2632.     The standard Parse-O-Matic package contains a map file (ASC2EBCD.MPF) which
  2633.     will translate ASCII files into EBCDIC files -- and vice-versa.
  2634.  
  2635.     NOTE:  EBCDIC is a character representation used on certain large mainframe
  2636.            computers.  Both ASCII and EBCDIC characters are eight bits long,
  2637.            but EBCDIC uses different bit patterns for most characters.
  2638.  
  2639.     Since both the "find" and "replace with" columns in ASC2EBCD.MPF are only
  2640.     one character wide, and since there is no duplication within either column,
  2641.     the translation process is perfectly reversible.  For example:
  2642.  
  2643.     PROLOGUE
  2644.       CHOP     1 20                                <-- Read 20 bytes at a time
  2645.       MAPFILE  "ASC2EBCD.MPF" "EBCDIC"             <-+
  2646.       MAPFILE  "ASC2EBCD.MPF" "ASCII" "TRANSPOSE"    | Set up maps
  2647.       MAPFILE  "BIN2CODE.MPF" "CODE"               <-+
  2648.     END
  2649.     SET      x = $FLINE                            <-+
  2650.     REMAP    x "CODE"                                | Display original text in
  2651.     OUTEND   |[ORIGINAL] [{$FLINE}]                  | normal & hex-coded form
  2652.     OUTEND   |[ORIGINAL] [{x}]                     <-+
  2653.     REMAP    $FLINE "EBCDIC"                       <-+
  2654.     SET      x = $FLINE                              | Convert to EBCDIC and
  2655.     REMAP    x "CODE"                                | display in coded form
  2656.     OUTEND   |[EBCDIC  ] [{x}]                     <-+
  2657.     REMAP    $FLINE "ASCII"                        <-+
  2658.     SET      x = $FLINE                              | Convert EBCDIC back to
  2659.     REMAP    x "CODE"                                | ASCII; display hex code
  2660.     OUTEND   |[ASCII   ] [{x}]                     <-+
  2661.     OUTEND   |                                     <-- Output a separator line
  2662.  
  2663.     You can run this POM file against any file, then view the output file.  You
  2664.     will see how the original text is converted into EBCDIC and then the EBCDIC
  2665.     is converted back to ASCII.  (Most of the data in the output file is
  2666.     represented in "hex dump" format, since your computer is not designed to
  2667.     display EBCDIC.)
  2668.  
  2669.     TRANSPOSE will often let you use a single map file instead of two, but
  2670.     before using this technique you should carefully consider how mapping will
  2671.     take place (see "Irreversible Mapping", below).
  2672.  
  2673.  
  2674.     Irreversible Mapping
  2675.     --------------------
  2676.  
  2677.     Consider the following POM file:
  2678.     
  2679.     MAPFILE "MYMAP.MPF" "XYZ"
  2680.     MAPFILE "MYMAP.MPF" "ZYX" "TRANSPOSE"
  2681.     REMAP   $FLINE "XYZ"
  2682.     REMAP   $FLINE "ZYX"
  2683.     OUTEND  |{$FLINE}
  2684.  
  2685.     In many cases, this is equivalent to the following one-line POM file:
  2686.  
  2687.     OUTEND  |{$FLINE}
  2688.  
  2689.     because the first REMAP changes $FLINE one way, and the second REMAP
  2690.     changes it back.
  2691.  
  2692.     This is not true in ALL cases, however.  In some circumstances a REMAP is
  2693.     not reversible.  Consider the following map file:
  2694.  
  2695.     "XYZ"  "CAB"
  2696.     "ABC"  "C"
  2697.     "DEF"  "ABC"
  2698.  
  2699.     Now consider the following sequence of events.  (The * and # characters
  2700.     show what gets replaced in each step.)
  2701.  
  2702.                  Original string   . . . . . . . . .   ABCDEF
  2703.                                                        ***###
  2704.                                                       
  2705.                                                        *###
  2706.                  Remap produces this result  . . . .   CABC
  2707.                                                        ***
  2708.                                                        
  2709.                                                        ***
  2710.                  Transposed remap of result  . . . .   XYZC
  2711.  
  2712.     If you follow the steps of the substitutions, you will see where the
  2713.     confusion arises.  As a general rule, simple substitutions (with no
  2714.     duplications in whole or in part) are reversible, but if you have any
  2715.     doubts, you can always take the safe route and use a separate map file
  2716.     for each direction.  (See "Search Order", above, for additional insight
  2717.     into this matter.)
  2718.  
  2719.     
  2720.     Memory Limitations
  2721.     ------------------
  2722.  
  2723.     The MAPFILE command reads the map data into RAM memory.  You will normally
  2724.     have sufficient memory for thousands of bytes worth of mappings. However,
  2725.     if you do not have enough memory to hold the data, Parse-O-Matic will
  2726.     display an error message, then terminate.  (See "Solving Memory Problems")
  2727.  
  2728.     To help you track memory usage, the MAPFILE command records memory status
  2729.     (bytes used and bytes left) in the processing log (see "Logging").
  2730.  
  2731.  
  2732.     An Example of Remapping
  2733.     -----------------------
  2734.  
  2735.     The standard Parse-O-Matic package contains two sample map files:
  2736.  
  2737.     BIN2CODE.MPF maps single bytes to hex codes  (e.g. Hex $31 becomes "31 ")
  2738.     BIN2CHAR.MPF maps single bytes to either printable characters or periods
  2739.  
  2740.     You can view these files with the SEE program (included with Parse-O-Matic)
  2741.     or you can load them into a text editor program.
  2742.  
  2743.     Here is a POM file that uses the sample map files to create a hex dump of a
  2744.     binary file:
  2745.  
  2746.     CHOP    1 16                  <-- Read the file 16 bytes at a time
  2747.     SETLEN  w $FLINE              <-- Get the actual number of bytes read
  2748.     BEGIN w <> "16"
  2749.       PAD $FLINE "R" #0 "16"      <-- If less than 16 bytes, pad with nulls
  2750.     END
  2751.     SET     x = $FLINE            <-- Make a copy of $FLINE
  2752.     SET     y = $FLINE            <-- Make a copy of $FLINE
  2753.     MAPFILE "BIN2CHAR" "CHAR"     <-- See Note
  2754.     MAPFILE "BIN2CODE.MPF" "CODE"
  2755.     REMAP   x "CHAR"              <-- Change the bytes to printable characters
  2756.     REMAP   y "CODE"              <-- Change the bytes to hex codes
  2757.     OUTEND  |x y                  <-- Output the line
  2758.  
  2759.     Note:  Since the file name (value1) does not have an extension,
  2760.            Parse-O-Matic will add the .MPF extension.  Thus, the actual file
  2761.            name Parse-O-Matic looks for is "BIN2CHAR.MPF".
  2762.  
  2763.  
  2764.                                  -----------------
  2765.                                  The REMAP Command
  2766.                                  -----------------
  2767.  
  2768.     FORMAT:        REMAP var1 value1
  2769.  
  2770.     PURPOSE:       REMAP transforms sub-strings into other strings
  2771.  
  2772.     PARAMETERS:    var1   is the variable being transformed
  2773.                    value1 is the map name (see "The MapFile Command")
  2774.  
  2775.     ALTERNATIVES:  The LOOKUP and CHANGE commands.
  2776.  
  2777.     SEE ALSO:      "The MapFile Command"
  2778.  
  2779.     The REMAP command performs intensive substitutions on a variable.  It is
  2780.     equivalent to a large number of CHANGE commands, but has the following
  2781.     advantages:
  2782.  
  2783.     - It is faster than using a large number of CHANGEs
  2784.     - It does not expend your available values (see "Values")
  2785.     - It prevents multiple substitutions
  2786.  
  2787.  
  2788.     REMAP Versus CHANGE
  2789.     -------------------
  2790.  
  2791.     The "multiple substitution" issue is most important distinction between
  2792.     CHANGE and REMAP.  REMAP protects substituted text from being
  2793.     resubstituted.  Consider the following POM lines:
  2794.  
  2795.     SET    x = "cat dog mouse"
  2796.     CHANGE x "cat" "dog"
  2797.     CHANGE x "dog" "cat"
  2798.  
  2799.     You might expect these lines to change x to "Dog Cat Mouse", but the actual
  2800.     result is "cat cat mouse".  The first CHANGE command sets the x variable to
  2801.     "dog dog mouse".  The next command changes the cats into dogs!
  2802.  
  2803.     You can avoid this problem by using intermediate substitutions or some such
  2804.     work-around, but this ends up complicating the POM file considerably.
  2805.     Moreover, this approach can be unwieldy if you have to perform a large
  2806.     number of substitutions.
  2807.  
  2808.  
  2809.     Using REMAP
  2810.     -----------
  2811.  
  2812.     To accomplish the "cat/dog" substitution mentioned earlier, you can create
  2813.     a map file (named CATDOG.MPF) with a text editor.  It will look like this:
  2814.  
  2815.     "cat"  "dog"
  2816.     "dog"  "cat"
  2817.  
  2818.     Your POM file will then look like this:
  2819.  
  2820.     MAPFILE "CATDOG.MPF" "PETS"
  2821.     SET     x = "cat dog mouse"
  2822.     REMAP   x "PETS"
  2823.  
  2824.     This will change the x variable to "dog cat mouse".
  2825.  
  2826.     For another example of the REMAP command, see "The MapFile Command".
  2827.  
  2828.  
  2829.     ===========================================================================
  2830.                                  FREE-FORM COMMANDS
  2831.     ===========================================================================
  2832.  
  2833.  
  2834.                             ----------------------------
  2835.                             What are Free-Form Commands?
  2836.                             ----------------------------
  2837.  
  2838.     The free-form commands are used for extracting information from an input
  2839.     line that does not have its data in precise columns.  Consider the
  2840.     following input file:
  2841.  
  2842.     Mouse     Gazelle   Mouse     Elephant
  2843.     Dog       Giraffe   Elk       Mongoose
  2844.     Monkey    Snake     Caribou   Trout
  2845.     |         |         |         |
  2846.     Column 1  Col 11    Col 21    Col 31
  2847.  
  2848.     Extracting data that is arranged in tidy columns is simple -- all you need
  2849.     is the SET command.  However, you will need a more powerful command if the
  2850.     data is "free-form", like this:
  2851.  
  2852.     Mouse,Gazelle,Mouse,Elephant
  2853.     Dog,Giraffe,Elk,Mongoose
  2854.     Monkey,Snake,Caribou,Trout
  2855.  
  2856.     The data is not arranged in tidy columns.  For tasks like this, you need
  2857.     the free-form commands.
  2858.  
  2859.  
  2860.                                  -----------------
  2861.                                  The PARSE Command
  2862.                                  -----------------
  2863.  
  2864.     FORMAT:        PARSE var1 value1 value2 value3 [value4]
  2865.                          :    :      :      :       :
  2866.     MEANING:       Variable   Source From   To      Control
  2867.  
  2868.     PURPOSE:       PARSE sets var1 to the text (found in value1) between
  2869.                    text fragments specified by value2 and value3.
  2870.  
  2871.     PARAMETERS:    var1   is the variable being set
  2872.                    value1 is the source text being read
  2873.                    value2 specifies the starting position
  2874.                    value3 specifies the ending position
  2875.                    value4 is the optional control setting
  2876.  
  2877.     DEFAULTS:      value4 = "X"
  2878.  
  2879.     ALTERNATIVES:  The PEEL command, and COPY used with FINDPOSN.
  2880.  
  2881.     Consider the the following free-form data:
  2882.  
  2883.     Mouse,Gazelle,Mouse,Elephant
  2884.     Dog,Giraffe,Elk,Mongoose
  2885.     Monkey,Snake,Caribou,Trout
  2886.  
  2887.     The PARSE command lets you extract the "Nth" item.  For example, to extract
  2888.     the third item in each line in the free-form example above, you could use
  2889.     this command:
  2890.  
  2891.     PARSE  xyz  $FLINE  "2*,"  "3*,"
  2892.  
  2893.     This means "set the variable xyz by looking in $FLINE (the line just read
  2894.     from the input file) and taking everything between the second comma and the
  2895.     third comma".  For the three lines in the sample input file, the variable
  2896.     xyz is set to Mouse, then Elk, then Caribou.
  2897.  
  2898.  
  2899.     Decapsulators
  2900.     -------------
  2901.  
  2902.     In the "From" specification in the previous example (i.e. the "2*," part
  2903.     of the command):
  2904.  
  2905.           2    means "the second occurrence"
  2906.           *    is a delimiter to mark the end of the occurrence number
  2907.           ,    is the text you are looking for
  2908.  
  2909.     Both the "From" and "To" specifications use this format.  Commands using
  2910.     this format are said to use "decapsulators", because you are extracting
  2911.     text that is encapsulated (i.e. surrounded) by other text.
  2912.  
  2913.     Decapsulators may be used to find more than a single character.  The
  2914.     surrounding text can be up to 80 characters long.  Let's say the input file
  2915.     looks like this:
  2916.  
  2917.     Mouse:::Gazelle:::Mouse:::Elephant
  2918.     Dog:::Giraffe:::Elk:::Mongoose
  2919.     Monkey:::Snake:::Caribou:::Trout
  2920.  
  2921.     You can extract the third item in each line with this command:
  2922.  
  2923.            PARSE  xyz  $FLINE  "2*:::"  "3*:::"
  2924.                   ___  ______   _ ___    _ ___
  2925.                    |     |      |  |     |  |
  2926.      Variable to set     |      |  |     |  |
  2927.         The value to parse      |  |     |  "To" text being sought
  2928.          "From" occurrence number  |     "To" occurrence number
  2929.             "From" text being sought
  2930.  
  2931.     This command sets the variable xyz to Mouse, then Elk, then Caribou.
  2932.  
  2933.  
  2934.     Sample Application
  2935.     ------------------
  2936.  
  2937.     The PARSE command is particularly useful for extracting information from
  2938.     comma-delimited files.  Here is an example of a comma-delimited file:
  2939.  
  2940.     "Mouse","Gazelle","Mouse","Elephant"
  2941.     "Dog","Giraffe","Elk","Mongoose"
  2942.     "Monkey","Snake","Caribou","Trout"
  2943.  
  2944.     You can extract all the fields with this series of commands (note the use
  2945.     of doubled-up quotes to represent a single quotation mark -- see the
  2946.     section "Delimiters" for details):
  2947.  
  2948.     PARSE  field1  $FLINE  "1*"""  "2*"""
  2949.     PARSE  field2  $FLINE  "3*"""  "4*"""
  2950.     PARSE  field3  $FLINE  "5*"""  "6*"""
  2951.     PARSE  field4  $FLINE  "7*"""  "8*"""
  2952.  
  2953.     For the first line of the sample input file, field1 is set to Mouse, field2
  2954.     is set to Gazelle, and so on.
  2955.  
  2956.  
  2957.     The Occurence Number
  2958.     --------------------
  2959.  
  2960.     The occurrence number must be between 1 and 255.  The following lines are
  2961.     not valid PARSE commands:
  2962.  
  2963.     PARSE  xyz  $FLINE  "0*,"  "1*,"    <-- "From" decapsulator invalid: uses 0
  2964.     PARSE  xyz  $FLINE  "1*,"  "256*,"  <-- "To" decapsulator invalid: uses 256
  2965.  
  2966.     The occurrence number must always be followed by a "*" so you can search
  2967.     for a number.  Consider the following example (the meaning of which would
  2968.     be unclear without the "*" delimiter):
  2969.  
  2970.     PARSE  xyz  "XXX2YYY2ZZZ2"  "1*2"  "2*2"
  2971.  
  2972.     This sets xyz to the text occuring between the first "2" and the second
  2973.     "2".  In other words, xyz is set to "YYY".
  2974.  
  2975.  
  2976.     Finding the Last Occurence
  2977.     --------------------------
  2978.  
  2979.     A decapsulator can refer to "the LAST occurence":
  2980.  
  2981.     PARSE  xyz  "AaaBAbbBAccB"  ">*A"  ">*B"
  2982.  
  2983.     In both decapsulators, the ">" symbol means "the last occurence".  Thus,
  2984.     the command tells Parse-O-Matic, "Set the xyz variable to everything
  2985.     between the last A and the last B".  This sets the xyz variable to "cc".
  2986.  
  2987.     You can also use the "<" character to mean "the FIRST occurence", although
  2988.     this is somewhat redundant, since the following commands are equivalent:
  2989.  
  2990.     PARSE  xyz  "AaaBAbbBAccB"  "<*A"  "<*B"
  2991.     PARSE  xyz  "AaaBAbbBAccB"  "1*A"  "1*B"
  2992.     PARSE  xyz  "AaaBAbbBAccB"  "A"  "B"
  2993.  
  2994.     All three commands set the xyz variable to "aa".
  2995.  
  2996.  
  2997.     Unsuccessful Searches
  2998.     ---------------------
  2999.  
  3000.     If PARSE does not find the search text, the variable will be set to a null
  3001.     ("").  Here are two examples:
  3002.  
  3003.     PARSE  abc  "ABCDEFGHIJ"  "1*K"  "1*J"   <-- There is no "K"
  3004.     PARSE  abc  "ABCDEFGHIJ"  "1*A"  "1*X"   <-- There is no "X"
  3005.  
  3006.     If the "from" value is less than the "to" value, Parse-O-Matic will display
  3007.     an error message, then terminate.  For example:
  3008.  
  3009.     PARSE  abc  "ABCDEFGHIJ"  "1*J"  "1*A"   <-- "J" comes after "A"
  3010.  
  3011.     This kind of failure typically happens if the input data contains an odd
  3012.     arrangement of text that you had not foreseen.
  3013.  
  3014.  
  3015.     The Control Setting
  3016.     -------------------
  3017.  
  3018.     The PARSE command has an optional "Control" parameter, which tells PARSE
  3019.     whether to include or exclude the surrounding text that was found.  By
  3020.     default (as shown in all of the preceding examples), the delimiting text
  3021.     is excluded.  However, if you want to include it, you can add "I" at the
  3022.     end of the PARSE command, as in this example:
  3023.  
  3024.     PARSE  xyz  "aXcaYcaZc"  "2*a"  "2*c"  "I"
  3025.  
  3026.     This tells Parse-O-Matic to give you everything between the second "a" and
  3027.     the second "c" -- including the "a" and "c".  In other words, this sets the
  3028.     variable xyz to "aYc".  You can also set the Control specification to "X"
  3029.     (meaning "exclude"), although since this is the default setting for PARSE,
  3030.     it really isn't necessary.  Here is an example:
  3031.  
  3032.     PARSE  xyz  "a1ca2ca3c"  "2*a"  "2*c"  "X"
  3033.  
  3034.     This sets the variable xyz to "2".
  3035.  
  3036.  
  3037.     The Plain Decapsulator
  3038.     ----------------------
  3039.  
  3040.     The occurrence number is not always needed.  Either the "From" or "To"
  3041.     decapsulator can be represented as a plain string, as follows:
  3042.  
  3043.     PARSE $FLINE "ABC" "XYZ"
  3044.  
  3045.     This means:
  3046.  
  3047.     - Start at the first "ABC" found in the value being parsed
  3048.     - End with the first "XYZ" found in the value being parsed
  3049.  
  3050.  
  3051.     The Null Decapsulator
  3052.     ---------------------
  3053.  
  3054.     Here is helpful variation of the "From" decapsulator:
  3055.  
  3056.     ""   means "Start from the first character in the value being parsed"
  3057.  
  3058.     A similar variation can be used with the "To" decapsulator:
  3059.  
  3060.     ""   means "End with the last character in the value being parsed"
  3061.  
  3062.     If you use the null ("") decapsulator for "From" or "To", the "found" value
  3063.     (the first character for "From", or the last character for "To") will
  3064.     always be included (see "Overlapping Decapsulators" for the single
  3065.     exception to this rule).  Here is an example:
  3066.  
  3067.     PARSE  xyz  "ABCABCABC"  ""  "2*C"
  3068.  
  3069.     This sets the variable xyz to "ABCAB".  The "From" value (i.e. the first
  3070.     character) is NOT excluded.  However, when PARSE finds the "To" value (i.e.
  3071.     the second occurrence of the letter C) it IS excluded.  If you want to
  3072.     include the second "C", you should write the command this way:
  3073.  
  3074.     PARSE  xyz  "ABCABCABC"  ""  "2*C"  "I"
  3075.  
  3076.     The following two commands accomplish the same thing:
  3077.  
  3078.     PARSE  xyz  "ABCD"  ""  ""
  3079.     SET    xyz  "ABCD"
  3080.  
  3081.     They are equivalent because the PARSE command means "Set the variable xyz
  3082.     with everything between (and including) the first and last character".
  3083.  
  3084.  
  3085.     Null Decapsulators Versus Exclusion
  3086.     -----------------------------------
  3087.  
  3088.     The reason that PARSE treats the null ("") decapsulator differently may
  3089.     not be immediately obvious, since the examples given here are very simple,
  3090.     and not representative of "real world" applications. However, in day-to-day
  3091.     usage, you will frequently find it helpful to be able to specify a command
  3092.     that says, "Give me everything from the beginning of the line to just
  3093.     before such-and-such".
  3094.  
  3095.     Here is a command that means "Give me everything from just after the dollar
  3096.     sign, to the end of the line":
  3097.  
  3098.     PARSE  xyz  "I'd like to have $250.00"  "1*$"  ""
  3099.  
  3100.     This sets xyz to "250.00".  If you want to include the dollar sign, write
  3101.     the command this way:
  3102.  
  3103.     PARSE  xyz  "I'd like to have $250.00"  "1*$"  ""  "I"
  3104.  
  3105.  
  3106.     Overlapping Decapsulators
  3107.     -------------------------
  3108.  
  3109.     Earlier, it was mentioned that the text found by the null decapsulator is
  3110.     "always included" and is not affected by the "X" (Exclude) control.  There
  3111.     is one exception to this:  if the null decapsulator's "found text" is
  3112.     contained in the text found by the other decapsulator, it WILL be affected.
  3113.     For example:
  3114.  
  3115.     PARSE x "ABCDEFABCDEF" "" "1*AB" "X"
  3116.  
  3117.     This command tells Parse-O-Matic "give me everything between the first
  3118.     character and the first occurence of AB".  Since the two items overlap
  3119.     (i.e. the first "AB" includes the first character), the first character
  3120.     does indeed get excluded. As a result, the x variable is set to an empty
  3121.     string ("").
  3122.  
  3123.     Here is another example:
  3124.  
  3125.     PARSE x "ABCDEFABCDEF" ">*F" "" "X"
  3126.  
  3127.     This command tells Parse-O-Matic "give me everything between the last
  3128.     occurence of F and the last character".  Both decapsulators refer to the
  3129.     same character (i.e. the final "F"), so it is excluded. As a result, the x
  3130.     variable is set to an empty string ("").
  3131.  
  3132.     NOTE:  In some circumstances, the FINDPOSN command is NOT affected by this
  3133.            exception.  It will do its best to make sense of your request if the
  3134.            decapsulators overlap, and one of them is a null decapsulator.  For
  3135.            details, see "The FindPosn Command".
  3136.  
  3137.  
  3138.     Parsing Empty Fields
  3139.     --------------------
  3140.  
  3141.     Consider the following command:
  3142.  
  3143.     PARSE x ",,,JOHN,SMITH" "2*," "3*,"
  3144.  
  3145.     There is nothing between the second and third comma, so the x variable
  3146.     is set to "" (an empty string).
  3147.  
  3148.     Now consider this command:
  3149.  
  3150.     PARSE x ",,,JOHN,SMITH" "" ","
  3151.  
  3152.     You are asking for everything from the first character to the first
  3153.     comma (which also happens to be the first character).  Obviously, there is
  3154.     nothing "between" the two characters, so the x variable would be set to ""
  3155.     (an empty string).
  3156.     
  3157.  
  3158.     Additional Examples
  3159.     -------------------
  3160.  
  3161.     For more examples of the PARSE command, see the demonstrations provided
  3162.     with Parse-O-Matic (type START at the DOS prompt, or run START.BAT from
  3163.     Windows or OS/2, then select TUTORIAL).
  3164.  
  3165.  
  3166.                                 ----------------
  3167.                                 The PEEL Command
  3168.                                 ----------------
  3169.  
  3170.     FORMAT:        PEEL  var1 var2   value1 value2 [value3]
  3171.                          :    :      :      :       :
  3172.     MEANING:       Variable   Source From   To      Control
  3173.  
  3174.     PURPOSE:       The PEEL command works just like PARSE, but after setting
  3175.                    var1, it REMOVES the parsed value (including the delimiters)
  3176.                    from var2.
  3177.  
  3178.     PARAMETERS:    var1   is the variable being set
  3179.                    var2   is the source text being read
  3180.                    value1 specifies the starting position
  3181.                    value2 specifies the ending position
  3182.                    value3 is the optional control setting
  3183.  
  3184.     DEFAULTS:      value3 = "X"
  3185.  
  3186.     When you are breaking up a complex line into fields, PEEL can simplify
  3187.     matters considerably, because the line being interpreted gradually becomes
  3188.     less complex.
  3189.  
  3190.     Here is a simple example.  Let's say you have an input file containing a
  3191.     single line:
  3192.  
  3193.     AA/BB/CC/DD
  3194.  
  3195.     If you run this POM file against the input file:
  3196.  
  3197.     PEEL   x $FLINE "" "/"       <-- Strip out the AA and remove the /
  3198.     OUTEND |{x}
  3199.     PEEL   x $FLINE "" "/"       <-- Strip out the BB and remove the /
  3200.     OUTEND |{x}
  3201.     PEEL   x $FLINE "" "/"       <-- Strip out the CC and remove the /
  3202.     OUTEND |{x}
  3203.     OUTEND |{$FLINE}
  3204.  
  3205.     then the output file will look like this:
  3206.  
  3207.     AA
  3208.     BB
  3209.     CC
  3210.     DD
  3211.  
  3212.     What is happening is that $FLINE is gradually being stripped of the text
  3213.     that is being found.  After the first PEEL, $FLINE contains "BB/CC/DD",
  3214.     and so on.  After the final PEEL, $FLINE only contains "DD".
  3215.  
  3216.  
  3217.     The Control Setting
  3218.     -------------------
  3219.  
  3220.     The "I" and "X" control parameters behave the same way as they do in the
  3221.     PARSE command: they specify whether or not the surrounding text is included
  3222.     in var1.  Take note, however, that the starting and ending characters
  3223.     are always removed from var2, along with the "found" text, regardless of
  3224.     the control parameter.  In other words, the control parameter only affects
  3225.     the first variable (x in the example above), not the second ($FLINE in the
  3226.     example).
  3227.  
  3228.  
  3229.     Parsing Empty Fields
  3230.     --------------------
  3231.  
  3232.     Consider the following commands:
  3233.  
  3234.     SET   z = ",,,JOHN,SMITH"
  3235.     PEEL  x z "2*," "3*,"
  3236.  
  3237.     There is nothing between the second and third comma, so the x variable
  3238.     is set to "" (an empty string).  After the PEEL command, the z variable
  3239.     will be two commas shorter (",JOHN,SMITH,23.00").  If you are trying to
  3240.     extract data from a comma-delimited line, this is probably not what you
  3241.     want (since it gets rid of two commas).  When taking apart a delimited
  3242.     file, it often makes sense to start peeling from the left side of the
  3243.     string.  Consider these commands:
  3244.  
  3245.     SET   z = ",,,JOHN,SMITH"
  3246.     PEEL  x z "" ","
  3247.  
  3248.     You are asking for everything from the first character to the first
  3249.     comma (which also happens to be the first character).  Obviously, there is
  3250.     nothing "between" the two characters, so the x variable would be set to ""
  3251.     (an empty string).  After the PEEL command, the z variable will be one
  3252.     comma shorter (",,JOHN,SMITH").
  3253.  
  3254.  
  3255.     The Left-Peeling Method
  3256.     -----------------------
  3257.  
  3258.     You can use the "left-peeling" method to take apart an entire line.  This
  3259.     is especially useful when interpreting a comma-delimited file.
  3260.  
  3261.     SET   z = ",,MARY,JONES,"
  3262.     PEEL  a z "" ","                 <-- Sets the a variable to ""
  3263.     PEEL  b z "" ","                 <-- Sets the b variable to ""
  3264.     PEEL  c z "" ","                 <-- Sets the c variable to "MARY"
  3265.     PEEL  d z "" ","                 <-- Sets the d variable to "JONES"
  3266.     SET   e = z                      <-- Sets the e variable to ""
  3267.  
  3268.     The e variable is null because there is nothing after the last comma -- in
  3269.     other words, the final field is empty.  If the initial value of the z
  3270.     variable was ",,MARY,JONES,99" then the e variable would be set to "99".
  3271.  
  3272.  
  3273.  
  3274.     ===========================================================================
  3275.                                 POSITIONAL COMMANDS
  3276.     ===========================================================================
  3277.              
  3278.                  
  3279.                                  ------------------
  3280.                                  General Discussion
  3281.                                  ------------------
  3282.  
  3283.     NOTE:  If you are a programmer, you may be tempted to use positional
  3284.            commands even when other Parse-O-Matic commands are more efficient.
  3285.            The positional approach is reminiscent of the parsing strategies
  3286.            used in traditional programming languages, so you may use them
  3287.            because of their familiarity.  The following material discusses
  3288.            this issue, to help you to create shorter, faster POM files.
  3289.  
  3290.  
  3291.     What are Positional Commands?
  3292.     -----------------------------
  3293.  
  3294.     Parse-O-Matic's positional commands let you work with the numeric position
  3295.     of one text string in another.  For example, if the variable xyz contains
  3296.     the value "ABCD":
  3297.  
  3298.     SEARCH   POSITION
  3299.     STRING    IN xyz    COMMENTS
  3300.     ------   --------   -----------------------------------------
  3301.     "A"        "1"      "A" appears in the 1st position of "ABCD"
  3302.     "AB"       "1"
  3303.     "ABCD"     "1"
  3304.     "C"        "3"      "C" appears in the 3rd position of "ABCD"
  3305.     "CD"       "3"
  3306.     "D"        "4"
  3307.     "AC"       "0"      "0" since "AC" does not appear in "ABCD"
  3308.  
  3309.  
  3310.     Why Use Positional Commands?
  3311.     ----------------------------
  3312.  
  3313.     Positional commands give you the precise control you need for certain
  3314.     difficult parsing tasks. For example, if you want to obtain the last three
  3315.     characters of a string of known length (e.g. "ABCDEFG"), the standard
  3316.     approach is:
  3317.  
  3318.     SET abc = "ABCDEFG"
  3319.     SET xyz = abc[5 7]
  3320.  
  3321.     However, if the length of the string is not known, you can not use the
  3322.     substrings in [square brackets].  (To make Parse-O-Matic run as fast as
  3323.     possible for standard parsing jobs, you can not use variables within
  3324.     square brackets.)
  3325.  
  3326.     If the length of the string is not known, you need positional commands to
  3327.     obtain the last three characters.  Here is an example:
  3328.  
  3329.     SET    abc = "Unknown"
  3330.     SETLEN len abc
  3331.     CALC   lenminus = len "-" "2"
  3332.     COPY   xyz abc lenminus len
  3333.  
  3334.     The SETLEN command finds the length (i.e. the last position) of the abc
  3335.     variable.  In this case, the answer is "7", since "Unknown" is seven
  3336.     characters long.  The CALC command subtracts "2" from this length, setting
  3337.     the lenminus variable to "5".  Finally, the COPY command copies from
  3338.     position "5" to "7", setting the variable xyz to "own" -- the last three
  3339.     characters of the abc variable.
  3340.  
  3341.  
  3342.     A Cautionary Note
  3343.     -----------------
  3344.  
  3345.     Positional commands are useful for some applications, but many parsing jobs
  3346.     do not require them.  The commands SET, IF, PARSE and PEEL can usually do
  3347.     the same job with less effort. For example, the following approaches are
  3348.     equivalent:
  3349.  
  3350.                  STANDARD APPROACH       POSITIONAL APPROACH
  3351.                  -----------------       ---------------------
  3352.                  SET   abc "AB/CD"       SET      abc = "AB/CD"
  3353.                  PARSE xyz abc "/"       FINDPOSN n abc "/"
  3354.                                          COPY     xyz abc n+
  3355.  
  3356.     The positional approach requires more lines than the standard approach to
  3357.     extracting the characters after the "/" character.  Another problem is that
  3358.     because positional commands give you fine control of the parsing process,
  3359.     it is up to you to guard against exceptional situations.  Consider this
  3360.     example:
  3361.  
  3362.     FINDPOSN x $FLINE "/"
  3363.     CALC     x = x "+" "1"
  3364.     COPY     xyz $FLINE x
  3365.  
  3366.     If $FLINE (the current input line) contains the value "ABC/DEF":
  3367.  
  3368.     FINDPOSN sets x to "4" (the position of the "/" character)
  3369.     CALC     increases x to "5"
  3370.     COPY     sets xyz to "DEF" -- from position "5" to the end of $FLINE
  3371.  
  3372.     Unfortunately, a problem occurs if $FLINE does not contain a slash:
  3373.  
  3374.     FINDPOSN sets x to "0" (meaning the "/" was not found)
  3375.     CALC     increases x to "1"
  3376.     COPY     copies from position "1" to the end of $FLINE
  3377.  
  3378.     This may not be what you intended.  If you want to return a null string
  3379.     when $FLINE does not contain a slash, you could use a single PARSE command:
  3380.  
  3381.     PARSE xyz $FLINE "/"
  3382.  
  3383.     This copies anything after the slash to the xyz variable.  If $FLINE does
  3384.     not contain a slash, xyz is set to "".
  3385.  
  3386.     The precise control provided by Parse-O-Matic's positional commands makes
  3387.     them indispensible for certain parsing applications.  Just remember that
  3388.     with added power comes added responsibility:  you will sometimes have to
  3389.     add extra code to handle unusual situations.
  3390.  
  3391.  
  3392.                                  ------------------
  3393.                                  The SETLEN Command
  3394.                                  ------------------
  3395.  
  3396.     FORMAT:        SETLEN var1 value1
  3397.  
  3398.     PURPOSE:       SETLEN sets var1 to the length of value1.
  3399.  
  3400.     Here is an example of the SETLEN command:
  3401.  
  3402.     SET    x = "ABCD"
  3403.     SETLEN y x
  3404.  
  3405.     This sets variable y to "4".
  3406.  
  3407.     One handy application for SETLEN is to underline text.  For example:
  3408.  
  3409.     SET     name = $FLINE[1 15]
  3410.     TRIM    name "B" " "
  3411.     SETLEN  nlen name
  3412.     SET     uline = ""
  3413.     PAD     uline "L" "-" nlen
  3414.     OUTEND  |{name}
  3415.     OUTEND  |{uline}
  3416.  
  3417.     If the input line contains the name "JOHN SMITH", the output would be:
  3418.  
  3419.     JOHN SMITH
  3420.     ----------
  3421.  
  3422.     For another example that does underlining, see "POM and Wildcards".
  3423.  
  3424.  
  3425.                                  ------------------
  3426.                                  The DELETE Command
  3427.                                  ------------------
  3428.  
  3429.     FORMAT:        DELETE var1 value1 [value2]
  3430.  
  3431.     PURPOSE:       The DELETE command removes a range of characters (specified
  3432.                    as a starting and ending position) from a variable.
  3433.  
  3434.     PARAMETERS:    var1   is the variable from which characters will be removed
  3435.                    value1 is the starting position (e.g. "1" = First character)
  3436.                    value2 is the optional ending position; if it is omitted,
  3437.                           it is assumed to mean "the last character in var1"
  3438.  
  3439.     NOTES:         If value1 is null or "0", value1 = "1"
  3440.                    If value2 is null or "0", value2 = "last character in var1"
  3441.  
  3442.     ALTERNATIVES:  The PEEL, TRIM, CHANGE, SET and APPEND commands.
  3443.  
  3444.     Here is an example of the DELETE command:
  3445.  
  3446.     SET    x = "ABC///DEF"
  3447.     DELETE x "4" "6"
  3448.  
  3449.     This deletes from position 4 to 6, so the variable x is set to "ABCDEF".
  3450.  
  3451.     If value2 is omitted, DELETE assumes you wish to delete everything from
  3452.     the starting position to the end of the string.  For example:
  3453.  
  3454.     SET    x = "ABC///DEF"
  3455.     DELETE x "4"
  3456.  
  3457.     This sets x to "ABC".
  3458.  
  3459.  
  3460.                                   ----------------
  3461.                                   The COPY Command
  3462.                                   ----------------
  3463.  
  3464.     FORMAT:        COPY var1 value1 value2 [value3]
  3465.  
  3466.     PURPOSE:       The COPY command copies a range of characters (specified as
  3467.                    a starting and ending position) from a value to a variable.
  3468.  
  3469.     PARAMETERS:    var1   is the variable being set
  3470.                    value1 is the source value, from which you will copy text
  3471.                    value2 is the starting position (e.g. "1" = First character)
  3472.                    value3 is the optional ending position; if it is omitted,
  3473.                           it is assumed to mean "the last character in value1"
  3474.  
  3475.     NUMERICS:      Tabs, spaces and commas are stripped from value2 and value3
  3476.  
  3477.     NOTES:         If value2 is null or "0", value1 = "1"
  3478.                    If value3 is null or "0", value3 = "last char in value1"
  3479.  
  3480.     ALTERNATIVES:  The SET command.
  3481.  
  3482.     Here is an example of the COPY command:
  3483.  
  3484.     SET    x = "ABC///DEF"
  3485.     COPY   y x "4" "6"
  3486.  
  3487.     This copies from position 4 to 6, so the variable y is set to "///".
  3488.  
  3489.     If value2 is omitted, COPY assumes you wish to copy everything from the
  3490.     starting position to the end of the string.  For example:
  3491.  
  3492.     SET    x = "ABC///DEF"
  3493.     COPY   y x "4"
  3494.  
  3495.     This sets y to "///DEF".
  3496.  
  3497.     To make your POM files easier to read, you might consider padding the
  3498.     COPY command with an equals sign to remind you that a variable is being
  3499.     set. For example:
  3500.  
  3501.     COPY   y = x "4" "6"
  3502.  
  3503.     This emphasizes that the variable y is being set to a substring of x.
  3504.     For more information about padding, see "Padding for Clarity".
  3505.  
  3506.  
  3507.                                 -------------------
  3508.                                 The EXTRACT Command
  3509.                                 -------------------
  3510.  
  3511.     FORMAT:        EXTRACT var1 var2 value1 [value2]
  3512.  
  3513.     PURPOSE:       The EXTRACT command works like COPY, but removes the
  3514.                    characters from the source variable after copying them to
  3515.                    a variable.
  3516.  
  3517.     PARAMETERS:    var1   is the variable that will contain the characters
  3518.                           extracted from var2
  3519.                    var2   is the variable from which characters will be copied
  3520.                           to var1, then removed
  3521.                    value1 is the starting position (e.g. "1" = First character)
  3522.                    value2 is the optional ending position; if it is omitted,
  3523.                           it is assumed to mean "the last character in var2"
  3524.  
  3525.     NUMERICS:      Tabs, spaces and commas are stripped from value1 and value2
  3526.  
  3527.     NOTES:         If value1 is null or "0", value1 = "1"
  3528.                    If value2 is null or "0", value2 = "last character in var2"
  3529.  
  3530.     ALTERNATIVES:  The PEEL command.
  3531.  
  3532.     Here is an example of the EXTRACT command:
  3533.  
  3534.     SET     x = "ABC///DEF"
  3535.     EXTRACT y x "4" "6"
  3536.  
  3537.     This copies from position 4 to 6, so the variable y is set to "///".
  3538.     The characters copied to variable y are removed from x, so that it now
  3539.     contains the value "ABCDEF".
  3540.  
  3541.     If value2 is omitted, EXTRACT assumes you wish to extract everything from
  3542.     the starting position to the end of the string.  For example:
  3543.  
  3544.     SET     x = "ABC///DEF"
  3545.     EXTRACT y x "4"
  3546.  
  3547.     This sets y to "///DEF", while the variable x is set to "ABC" (i.e. the
  3548.     original value for x, with the extracted characters removed).
  3549.  
  3550.  
  3551.                                 --------------------
  3552.                                 The FINDPOSN Command
  3553.                                 --------------------
  3554.  
  3555.     FORMAT:        FINDPOSN var1 value1 value2 [value3 [value4]]
  3556.                             :    :      :       :       :
  3557.     MEANING:       1) Variable   Source Find    :       :
  3558.                    2) Variable   Source From    To      Control
  3559.  
  3560.     PURPOSE:       The FINDPOSN command finds one text string in another.  It
  3561.                    locates the starting or ending position of a string, or
  3562.                    a string delimited by one or two other strings.
  3563.  
  3564.     PARAMETERS:    var1   is the variable that will contain the position if
  3565.                           the string is found (e.g. "2" means it was found
  3566.                           in the second position of value1; "0" means the
  3567.                           string was not found)
  3568.                    value1 is the string being searched
  3569.                    value2 is the string being sought, or...
  3570.                              the left-most part of a string being sought
  3571.                    value3 is the right-most part of the string being sought;
  3572.                              if it is set to null (""), it is assumed to mean
  3573.                              "the last character in value1"
  3574.                    value4 is the control setting
  3575.  
  3576.     DEFAULTS:      value4 = "IS"
  3577.  
  3578.     SEE ALSO:      This section is much easier to understand if you have
  3579.                    studied "The Parse Command".
  3580.  
  3581.     There are two ways to use the FINDPOSN command:  the "Plain String Find"
  3582.     and the "Embedded String Find".  These are discussed below.
  3583.  
  3584.  
  3585.     The Plain String Find
  3586.     ---------------------
  3587.  
  3588.     In its simplest form, the Plain String Find locates a string (value2) in
  3589.     another string (value1) and assigns its position to a variable (var1).
  3590.     Here is an example:
  3591.  
  3592.     FINDPOSN x $FLINE "Fred"
  3593.  
  3594.     This looks for the first occurrence of "Fred" in $FLINE (the current input
  3595.     line).  If $FLINE contains "Hello Fred!", the command will set the variable
  3596.     x to "7", since "Fred" starts in the seventh character position.
  3597.  
  3598.  
  3599.     Using a Single Decapsulator
  3600.     ---------------------------
  3601.  
  3602.     Sometimes  you don't want to find the FIRST occurrence, but the second,
  3603.     third, and so on.  You can use a single decapsulator (see "The Parse
  3604.     Command") to specify this.  For example:
  3605.  
  3606.     SET      z = "This is the way to demonstrate the FINDPOSN command"
  3607.     FINDPOSN x z "the"
  3608.     FINDPOSN y z "2*the"
  3609.  
  3610.     The first FINDPOSN command finds the first occurrence of "the", using a
  3611.     plain string, so it sets the variable x to "9", since the first "the"
  3612.     starts in the ninth position.
  3613.  
  3614.     The second FINDPOSN command uses a decapsulator with the occurrence number
  3615.     "2*", which means "look for the second occurrence".  Thus, it sets the
  3616.     variable y to "32", since the second "the" occurs in that position.
  3617.  
  3618.     Incidentally, the first FINDPOSN could also have been written this way:
  3619.  
  3620.     FINDPOSN x z "1*the"
  3621.  
  3622.     which is another way of saying, "Look for the first occurrence".  However,
  3623.     if no occurrence number is specified, FINDPOSN assumes you are looking for
  3624.     the first occurrence.
  3625.  
  3626.  
  3627.     The Encapsulated String Find
  3628.     ----------------------------
  3629.  
  3630.     NOTE:  The Encapsulated String Find is very similar to the PARSE command.
  3631.            If you do not find the following discussion sufficiently
  3632.            instructive, you can gain some additional insight by reading the
  3633.            section of this manual entitled "The Parse Command".
  3634.  
  3635.     The Encapsulated String Find looks for a string that is encapsulated by
  3636.     (i.e. located between) two other strings.  This is useful if your input
  3637.     data contains text that is surrounded by delimiters.  One common example is
  3638.     the "comma-delimited" file (see "Why You Need Parse-O-Matic -- An Example"
  3639.     for a sample).  Here is another situation where data is surrounded by
  3640.     delimiters:
  3641.  
  3642.     |Mouse |Gazelle|Mouse  |Elephant|
  3643.     |Dog   |Giraffe|Elk    |Mongoose|
  3644.     |Monkey|Snake  |Caribou|Trout   |
  3645.  
  3646.     One can imagine an application that would create tabular data like this --
  3647.     cleverly (but annoyingly) reducing the column widths to the minimum.  This
  3648.     would make the column starting and ending positions unpredictable.
  3649.  
  3650.     You could use the PARSE command to obtain values from each column, but if
  3651.     you have a lot of data, it would be more efficient to determine the
  3652.     starting and ending positions at the outset.
  3653.  
  3654.     Let's say you wanted to extract the third column.  You could set up your
  3655.     POM file like this:
  3656.  
  3657.     BEGIN startposn = ""
  3658.       FINDPOSN startposn $FLINE "3*|" "4*|" "XS"
  3659.       FINDPOSN endposn   $FLINE "3*|" "4*|" "XE"
  3660.       HALT     startposn = "0" "Missing delimiter!"
  3661.     END
  3662.     COPY animal $FLINE startposn endposn
  3663.     OUTEND |{animal}
  3664.  
  3665.     The lines between the BEGIN and END are run only once for the entire
  3666.     parsing job, since they set the startposn variable to something other than
  3667.     a null ("") string.  (See "Uninitialized and Persistent Variables")
  3668.  
  3669.     The first FINDPOSN command uses the decapsulators "3*|" and "4*|" to locate
  3670.     the text between the third and fourth "|" delimiters, but because of the
  3671.     "XS" control value (described later), startposn is set to the position
  3672.     AFTER the delimiter. (Briefly, "XS" means "exclude the found text, and
  3673.     refer to the starting position of the text that follows it.)  Thus, the
  3674.     variable startposn is set to "12"; "Mouse" starts in the twelfth position.
  3675.  
  3676.     The second FINDPOSN command sets the ending position (endposn) in a similar
  3677.     way.  It finds the third and fourth "|" delimiters, but because of the "XE"
  3678.     control setting, it sets endposn to the position BEFORE the fourth
  3679.     delimiter. (Briefly, "XE" means "exclude the found text, and refer to the
  3680.     ending position of the text that precedes it.)
  3681.  
  3682.     The HALT command is simply a safeguard to ensure that the input data
  3683.     follows the correct format.  If the first FINDPOSN fails to find the
  3684.     third or fourth "|" delimiter, it will set startposn to "0" (meaning "not
  3685.     found").
  3686.  
  3687.     The COPY command copies $FLINE (the current input line) from the starting
  3688.     position (startposn) to the ending position (endposn).  This value is then
  3689.     output by the OUTEND command.
  3690.  
  3691.  
  3692.     Control Settings
  3693.     ----------------
  3694.  
  3695.     The control settings give you precise control of the part of the string
  3696.     to which you are referring.  Valid control settings are:
  3697.  
  3698.     SETTING  MEANING
  3699.     -------  -------
  3700.       IS     Include found text and report where the  entire   text starts
  3701.       IE     Include found text and report where the  entire   text ends
  3702.       XS     Exclude found text and report where the delimited text starts
  3703.       XE     Exclude found text and report where the delimited text ends
  3704.  
  3705.     NOTE:  While FINDPOSN greatly resembles the PARSE command, the default
  3706.            control setting is different.  In PARSE, the control setting is
  3707.            assumed to be "X" if it is omitted.  In FINDPOSN, however, the
  3708.            control setting is assumed to be "IS" if it is omitted.
  3709.  
  3710.     Let us assume that the we set the variable z as follows:
  3711.  
  3712.     SET z = "ABzzzCDEFzzzGH"
  3713.  
  3714.     This produces the following results:
  3715.  
  3716.             COMMAND                            VALUE FOR x VARIABLE
  3717.             ---------------------------------  --------------------
  3718.             FINDPOSN x z "1*zzz" "2*zzz" "IS"           "3"
  3719.             FINDPOSN x z "1*zzz" "2*zzz" "XS"           "6"
  3720.             FINDPOSN x z "1*zzz" "2*zzz" "XE"           "9"
  3721.             FINDPOSN x z "1*zzz" "2*zzz" "IE"          "12"
  3722.  
  3723.     The following illustration may make the results easier to understand:
  3724.  
  3725.     +------------------------------------------------------------------------+
  3726.     |                                                                        |
  3727.     | Measuring Scale:             12345678901234                            |
  3728.     |                              --------------                            |
  3729.     |         Command: FINDPOSN x "ABzzzCDEFzzzGH" "zzz" "2*zzz" "<control>" |
  3730.     |                                |  |  |  |                              |
  3731.     |   Control Value:              IS XS XE IE                              |
  3732.     |         Results:               3  6  9 12                              |
  3733.     |                                                                        |
  3734.     +------------------------------------------------------------------------+
  3735.  
  3736.     In the example, the control values have the following specific meanings:
  3737.  
  3738.     "IS" ("Include, Start") = start of entire text (from "1*zzz" to "2*zzz")
  3739.     "XS" ("Exclude, Start") = start of text after  the "from" item ("1*zzz")
  3740.     "XE" ("Exclude, End")   =  end  of text before the  "to"  item ("2*zzz")
  3741.     "IE" ("Include, End")   =  end  of entire text (from "1*zzz" to "2*zzz")
  3742.  
  3743.  
  3744.     Insoluble Searches
  3745.     ------------------
  3746.  
  3747.     FINDPOSN returns "0" (zero) when it can not find a string, or if it is
  3748.     presented with an insoluble dilemma.  Here are some examples:
  3749.  
  3750.     FINDPOSN x "CatDog" "Moose"        <-- "Moose" can not be found
  3751.     FINDPOSN x "ABCDEF" "A" "G"        <-- "G" can not be found
  3752.     FINDPOSN x "ABCDEF" "A" "2*E"      <-- There is no second "E"
  3753.  
  3754.     Here is another insoluble search:
  3755.  
  3756.     FINDPOSN x "ABCDEF" "C" "D" "XS"
  3757.     FINDPOSN x "ABCDEF" "C" "D" "XE"
  3758.  
  3759.     There is nothing between the "from" and "to" delimiters. Since we are
  3760.     excluding the delimiters themselves (with "XS" and "XE" specifications), we
  3761.     can not provide a "start" or "end" value for what we found -- we didn't
  3762.     find anything!  Hence, we have nothing for which to to return a starting or
  3763.     ending position.
  3764.  
  3765.  
  3766.     Null Decapsulators
  3767.     ------------------
  3768.  
  3769.     Consider these next two commands:
  3770.  
  3771.     FINDPOSN x "ABCDEF" "F" "" "XS"
  3772.     FINDPOSN x "ABCDEF" "F" "" "XE"
  3773.  
  3774.     What comes between "F" and the end of the string?  Bear in mind, however,
  3775.     that when you use a null ("") to mean "the last character", it is not
  3776.     excluded (see "The Null Decapsulator" in the section entitled "The Parse
  3777.     Command", for a discussion).  Thus, the two FINDPOSN commands "find" the
  3778.     final character "F", and both return "6".
  3779.  
  3780.     These both return "6" because the "F" is both the starting and ending
  3781.     position of what we found, and we included (rather than excluded) the
  3782.     starting and ending delimiters ("F" and the last character, respectively).
  3783.  
  3784.     Similarly, the following commands return a "1":
  3785.  
  3786.     FINDPOSN x "ABCDEF" "" "A" "XS"
  3787.     FINDPOSN x "ABCDEF" "" "A" "XE"
  3788.  
  3789.     Even though there is nothing between "A" and "the first character", the
  3790.     first character is not excluded, since we are using a null decapsulator.
  3791.     As a result, we find the string "A" and return its position, which is "1".
  3792.  
  3793.  
  3794.     Finding The Last Word
  3795.     ---------------------
  3796.  
  3797.     One common use for FINDPOSN is to find the last occurence of a word in a
  3798.     line of text.  Consider the following lines:
  3799.                    
  3800.     SET       z = "Parse-O-Matic is a fine product!"
  3801.     FINDPOSN  x z ">* " "" "XS"
  3802.  
  3803.     This will set the x variable to 25 (the position of the final word).  The
  3804.     command looks for the last "space" character (which is in position 24),
  3805.     then (because of the "XS" control) returns the position of the character
  3806.     following it.
  3807.  
  3808.  
  3809.     Who Needs This?
  3810.     ---------------
  3811.  
  3812.     At this point, you may be wondering, "Why do I need to have this kind of
  3813.     precise control?"  Well, in most cases you don't, so you will tend to use
  3814.     the "Plain String Find" (described earlier).  However, certain complex
  3815.     parsing applications demand that you make a distinction between the text
  3816.     that encapsulated a piece of text, and the encapsulated text itself.  When
  3817.     faced with this kind of task, you will see that Parse-O-Matic's FINDPOSN
  3818.     command lets you accomplish in one line what would take dozens of lines in
  3819.     a traditional programming language.
  3820.  
  3821.  
  3822.  
  3823.     ===========================================================================
  3824.                                    DATE COMMANDS
  3825.     ===========================================================================
  3826.  
  3827.  
  3828.                                  ------------------
  3829.                                  General Discussion
  3830.                                  ------------------
  3831.  
  3832.     Parse-O-Matic's date-oriented commands provide you with a convenient way to
  3833.     work with dates.  While you can accomplish the same thing using other
  3834.     Parse-O-Matic commands (LOOKUP, PAD etc.), the date functions are optimized
  3835.     for speed, so if your parsing job does a lot of date-format conversions, it
  3836.     will run faster.
  3837.  
  3838.  
  3839.     The POMDATE.CFG File
  3840.     --------------------
  3841.  
  3842.     When a date command is first executed, Parse-O-Matic reads in a file named
  3843.     POMDATE.CFG.  (The method by which Parse-O-Matic finds the file is
  3844.     discussed in the section "How Parse-O-Matic Searches for a File".)
  3845.  
  3846.     POMDATE.CFG is a self-documenting text file that contains the default
  3847.     date format string (explained later), and the names of the twelve months.
  3848.     You can edit this file with a standard text editor, or a word-processor in
  3849.     "generic text" mode.
  3850.  
  3851.     As originally supplied with Parse-O-Matic, the default date format string
  3852.     is "?y/?n/?d", which produces YY/MM/DD dates (e.g. July 1 1998 becomes
  3853.     98/07/01). You can change this to reflect your own preference.
  3854.  
  3855.     If you are parsing data in a language other than English, you can also
  3856.     change the names of the months.
  3857.  
  3858.  
  3859.     Date Formats
  3860.     ------------
  3861.  
  3862.     A date format is a sequence of characters that briefly describes the
  3863.     appearance of a date.  For example, the format "Y-T-?n" describes a
  3864.     year/month/day format that looks like this:  1996-JULY-02
  3865.  
  3866.     The following characters have a special meaning in the date format
  3867.     string:  d M m n T t Y y ?
  3868.  
  3869.     For these special characters, uppercase and lowercase are important.
  3870.     For example, "T" is not the same as "t".
  3871.  
  3872.     All characters other than the special characters are interpreted "as-is",
  3873.     and are included in the final date string.
  3874.  
  3875.     The following table explains the meaning of the special characters used
  3876.     to specify year, month and day, using the date July 2, 1998 for the
  3877.     examples:
  3878.  
  3879.          CHAR  MEANING                     SAMPLE FORMAT  SAMPLE RESULT
  3880.          ----  --------------------------  -------------  -------------
  3881.           Y    4-digit year                d-m-Y          2-Jul-1998
  3882.           y    1- or 2-digit year          d-m-y          2-Jul-98
  3883.           n    1- or 2-digit month         d/n/y          2/7/98
  3884.           m    3-letter month              d/m/y          2/Jul/98
  3885.           M    3-letter month (uppercase)  d M y          2 JUL 98
  3886.           t    Month                       t d, Y         July 2, 1998
  3887.           T    Month (uppercase)           T d Y          JULY 2 1998
  3888.           d    Day                         y/m/d          98/7/2
  3889.  
  3890.     The ? character can be used in the date format to pad out one-digit
  3891.     values to two digits.  The following table uses the date February 3, 2001
  3892.     for the examples:
  3893.  
  3894.                        SAMPLE DATE FORMAT   SAMPLE RESULT
  3895.                        ------------------   -------------
  3896.                        y-?n-?d              1-02-03
  3897.                        ?y/m/?d              01/Feb/03
  3898.                        ?n/?d Y              02/01 2001
  3899.                        t '?y                February '01
  3900.  
  3901.     As the last example shows, it is not necessary to use month, day and year;
  3902.     you can omit any item to obtain an abbreviated date.
  3903.  
  3904.  
  3905.                                  -----------------
  3906.                                  The TODAY Command
  3907.                                  -----------------
  3908.  
  3909.     FORMAT:        TODAY var1 [value1]
  3910.  
  3911.     PURPOSE:       The TODAY command sets a variable (var1) to today's date, in
  3912.                    a variety of formats.
  3913.  
  3914.     DEFAULTS:      If value1 is not specified, TODAY uses the default date
  3915.                    format, which is specified in the file POMDATE.CFG.
  3916.  
  3917.     NOTES:         For a discussion of date formats (including the default date
  3918.                    format), see the "General Discussion" section at the
  3919.                    beginning of this chapter.
  3920.  
  3921.     SEE ALSO:      "The Date Command"
  3922.  
  3923.     Assuming today's date is July 1 1998, here are some examples:
  3924.  
  3925.                COMMAND              THE VARIABLE xyz IS SET TO...
  3926.                -------------------  -----------------------------
  3927.                TODAY xyz            The default date format
  3928.                TODAY xyz ""         The default date format
  3929.                TODAY xyz "Y-M-?d"   1998-JUL-01
  3930.                TODAY xyz "t d Y"    July 1 1998
  3931.                TODAY xyz "t 'y"     July '98
  3932.  
  3933.     As the last example shows, it is not necessary to use month, day and year;
  3934.     you can omit any item to obtain an abbreviated date.
  3935.  
  3936.  
  3937.                                   ----------------
  3938.                                   The DATE Command
  3939.                                   ----------------
  3940.  
  3941.     FORMAT:        DATE var1 value1 value2 value3 [value4]
  3942.  
  3943.     PURPOSE:       The DATE command sets a variable (var1) to given year
  3944.                    (value1), month (value2) and day (value3), or a subset of
  3945.                    these items, in a variety of formats, as specified by the
  3946.                    format string (value4).
  3947.  
  3948.     PARAMETERS:    var1   is the variable being set
  3949.                    value1 is the year (e.g. "1998" or "98")
  3950.                    value2 is the month (e.g. "1" = January)
  3951.                    value3 is the day (1 to 31)
  3952.                    value4 is the date format
  3953.  
  3954.     NUMERICS:      Tabs, spaces and commas are stripped from value1, 2 and 3
  3955.  
  3956.     DEFAULTS:      If value4 is omitted, DATE uses the default date format,
  3957.                    which is specified in the file POMDATE.CFG.
  3958.  
  3959.     NOTES:         For a discussion of date formats (including the default date
  3960.                    format), see the "General Discussion" section at the
  3961.                    beginning of this chapter.
  3962.  
  3963.     SEE ALSO:      "The Today Command"
  3964.  
  3965.     Assuming the date being set is July 1 1998, here are some examples:
  3966.  
  3967.     COMMAND                             THE VARIABLE xyz IS SET TO...
  3968.     ----------------------------------  -----------------------------
  3969.     DATE xyz "98"   "07" "01"           The default date format
  3970.     DATE xyz "1998" "07" "01" ""        The default date format
  3971.     DATE xyz "98"    "7"  "1" "Y-M-?d"  1998-JUL-01
  3972.     DATE xyz "98"   "07" "01" "t d Y"   July 1 1998
  3973.     DATE xyz "98"    "7" "01" "t 'y"    July '98
  3974.     DATE xyz "98"    "7"   "" "t 'y"    July '98
  3975.  
  3976.     As the last two examples show, it is not necessary to use month, day and
  3977.     year; you can omit any item to obtain an abbreviated date.
  3978.  
  3979.     If a date is outside a valid range, Parse-O-Matic halts with an error.
  3980.     Acceptable value ranges are:  Year 0 to 9999; Month 1 to 12; Day 1 to 31
  3981.  
  3982.     If the year is between 0 and 99, Parse-O-Matic makes the following
  3983.     assumptions:
  3984.  
  3985.     - If the number is between 80 and 99, it means 1980 to 1999
  3986.     - If the number is between  0 and 89, it means 2000 to 2089
  3987.  
  3988.     Parse-O-Matic does not check that a date is "possible", so you could set
  3989.     a date to "February 31, 2001", even though February never has 31 days.
  3990.  
  3991.  
  3992.                                --------------------
  3993.                                The MONTHNUM Command
  3994.                                --------------------
  3995.  
  3996.     FORMAT:        MONTHNUM var1 value1
  3997.  
  3998.     PURPOSE:       The MONTHNUM command sets the month number of a given month.
  3999.  
  4000.     ALTERNATIVES:  The LOOKUP command.
  4001.  
  4002.     Here is an example of the MONTHNUM command:
  4003.  
  4004.     MONTHNUM xyz "February"
  4005.  
  4006.     This will set the variable xyz to "2".
  4007.  
  4008.     The comparison is performed on the basis of the number of characters
  4009.     available, without regard to case, so the following would also work:
  4010.  
  4011.     MONTHNUM xyz "FEB"
  4012.  
  4013.     If the result is ambiguous, Parse-O-Matic returns the first match.  For
  4014.     example:
  4015.  
  4016.     MONTHNUM xyz "JU"
  4017.  
  4018.     This will set xyz to "6", although it could refer to either June or July.
  4019.  
  4020.     If MONTHNUM can not find a match, it will return a null ("") string.
  4021.     For example:
  4022.  
  4023.     MONTHNUM xyz "ZZZ"
  4024.  
  4025.     Since no month starts with "ZZZ", this will set xyz to "".
  4026.  
  4027.     If you are writing a Parse-O-Matic application that will be run in several
  4028.     languages (using different POMDATE.CFG files), you should carefully study
  4029.     the names of the months in each language to avoid problems.  In English, it
  4030.     is always sufficient to provide the first three letters.  In French,
  4031.     however, you need at least four letters, to distinguish between "Juin"
  4032.     (June) and "Juillet" (July).
  4033.  
  4034.     Parse-O-Matic can use only one POMDATE.CFG file at a time, so the MONTHNUM
  4035.     command can not be used to translate month names from one language to
  4036.     another.  You can, however, accomplish the same thing with the LOOKUP
  4037.     command.
  4038.  
  4039.                                 --------------------
  4040.                                 The ZERODATE Command
  4041.                                 --------------------
  4042.  
  4043.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  4044.  
  4045.     FORMAT:        ZERODATE value1 value2 value3
  4046.  
  4047.     PURPOSE:       Specifies "day zero" for the date serial number used by the
  4048.                    MAKETEXT command when it uses the DATE predefined data type.
  4049.  
  4050.     PARAMETERS:    value1 is the year  (e.g. "1900")
  4051.                    value2 is the month (e.g. "12" for December)
  4052.                    value3 is the day   (e.g. "5")
  4053.  
  4054.     NUMERICS:      Tabs, spaces and commas are stripped from value1, 2 and 3
  4055.  
  4056.     DEFAULTS:      If the ZERODATE command is omitted, the zero date is assumed
  4057.                    to be Jan. 1, 1753 (equivalent to ZERODATE "1753" "1" "1").
  4058.  
  4059.     SEE ALSO:      "The MakeText Command" and "Predefined Data Types"
  4060.  
  4061.     A "date serial number" is a common method of representing a date in a data
  4062.     file.  It works by counting the number of days since a given date, taking
  4063.     into account the extra days for leap years.
  4064.  
  4065.     Leap years occur in every year that is divisible by four, with the
  4066.     exception of century years -- unless they are divisible by 400. Thus, 1900
  4067.     is not a leap year, but 2000 is.
  4068.  
  4069.     The ZERODATE command specifies "Day 0".  For example, if you specify
  4070.     ZERODATE "1918" "11" "11" (November 11, 1918), you get the following:
  4071.  
  4072.                      DATE               DATE SERIAL NUMBER
  4073.                      -----------------  ------------------
  4074.                      November  9, 1918          -2
  4075.                      November 10, 1918          -1
  4076.                      November 11, 1918           0
  4077.                      November 12, 1918           1
  4078.                      November 13, 1918           2
  4079.  
  4080.     ... and so on.  Most programs set the zero date far enough back that
  4081.     negative numbers are not encountered in normal usage.
  4082.  
  4083.     ZERODATE will not accept a starting year before "1753", which was the first
  4084.     full year that most of the Western world started using the Gregorian
  4085.     calendar.
  4086.  
  4087.  
  4088.  
  4089.     ===========================================================================
  4090.                                 CALCULATION COMMANDS
  4091.     ===========================================================================
  4092.  
  4093.  
  4094.                                   ----------------
  4095.                                   The CALC Command
  4096.                                   ----------------
  4097.  
  4098.     FORMAT:        CALC var1 value1 operation value2
  4099.  
  4100.     PURPOSE:       The CALC command performs an integer arithmetic operation on
  4101.                    the two values and assigns the answer to var1.
  4102.  
  4103.     NUMERICS:      Tabs, spaces and commas are stripped from value1 and value2
  4104.  
  4105.     ALTERNATIVES:  The CALCREAL command.
  4106.  
  4107.     SEE ALSO:      "Inline Incrementing and Decrementing"
  4108.  
  4109.     Integer arithmetic refers to whole numbers.  1, 10 and 10000 are integers,
  4110.     while 2.0, 3.14159 and 98.5 are not.
  4111.  
  4112.     Let's say your input file looks like this:
  4113.  
  4114.     DESCRIPTION      UNITS SOLD    UNIT PRICE
  4115.     -----------------------------------------
  4116.     Dog collar               15    $     3.00
  4117.     Cat collar               25    $     2.50
  4118.     Cat caller                3    $     7.25
  4119.     Birdie num-nums       1,305    $     6.25
  4120.     -----------------------------------------
  4121.     End of Data
  4122.     :                :        :     :       :
  4123.     :                :        :     :       :    (Column positions)
  4124.     1               18       27    33      41
  4125.  
  4126.     You can find out the total number of units sold (of all types) with the
  4127.     following POM file:
  4128.  
  4129.     IGNORE $FLINE[1 7] = "DESCRIP"
  4130.     IGNORE $FLINE[1 7] = "-------"
  4131.     BEGIN $FLINE = "End of Data"
  4132.       OUTEND |Total units sold = {units}
  4133.     ELSE
  4134.       CALC units = units "+" $FLINE[18 27]
  4135.     END
  4136.  
  4137.     As you can see from the example, all spaces and commas are stripped from
  4138.     the number.  Tab characters (ASCII 09) are also stripped.
  4139.  
  4140.     You will also notice that CALC can not be used for the prices, since they
  4141.     are not integer data.  To add up the prices, you must use the CALCREAL
  4142.     command (see "The CalcReal Command").
  4143.  
  4144.     Note in particular that the operation ("+" in this case) is in quotes.  If
  4145.     you omit the quotes, Parse-O-Matic will report an error.
  4146.  
  4147.     The following operations can be performed with CALC:
  4148.  
  4149.             SYMBOL     DESCRIPTION
  4150.             ---------  --------------------------------------------
  4151.             "+"        value1 plus value2
  4152.             "-"        value1 minus value2
  4153.             "*"        value1 times value2
  4154.             "/"        value1 divided by value2 (remainder ignored)
  4155.             "HIGHEST"  the larger number (value1 or value2)
  4156.             "LOWEST"   the smaller number (value1 or value2)
  4157.  
  4158.     Here are some more examples of the CALC command:
  4159.  
  4160.                    COMMAND                           ANSWER
  4161.                    --------------------------------  ------
  4162.                    CALC answer = "12" "/" "4"           "3"
  4163.                    CALC answer = "12" "HIGHEST" "4"    "12"
  4164.                    CALC answer = "12" "LOWEST"  "4"     "4"
  4165.                    CALC answer = "12" "-" "4"           "8"
  4166.                    CALC answer = "12" "+" "4"          "16"
  4167.                    CALC answer = "12" "*" "4"          "48"
  4168.  
  4169.     CALC can handle numbers between -2,147,483,648 and 2,147,483,647.
  4170.  
  4171.  
  4172.                                 --------------------
  4173.                                 The CALCREAL Command
  4174.                                 --------------------
  4175.  
  4176.     FORMAT:        CALCREAL var1 value1 operation value2 [fixed-decimals]
  4177.  
  4178.     PURPOSE:       CALCREAL works the same way as CALC, except that it handles
  4179.                    decimal numbers.
  4180.  
  4181.     NUMERICS:      Tabs, spaces and commas are stripped from value1, value2,
  4182.                    and the "fixed-decimals" value
  4183.  
  4184.     ALTERNATIVES:  The CALC command.
  4185.  
  4186.     Using the sample data given in the CALC section, you could write the
  4187.     following POM file:
  4188.  
  4189.     IGNORE $FLINE[1 7] = "DESCRIP"
  4190.     IGNORE $FLINE[1 7] = "-------"
  4191.     BEGIN $FLINE = "End of Data"
  4192.       OUTEND |Total units sold = {units}
  4193.       OUTEND |Total value sold = {value}
  4194.     ELSE
  4195.       CALC     units = units "+" $FLINE[18 27]
  4196.       CALCREAL value = value "+" $FLINE[33 41]
  4197.     END
  4198.  
  4199.     CALCREAL can handle values +/- 99,999,999,999, but its accuracy decreases
  4200.     when you are dealing with large numbers, as approximated below:
  4201.  
  4202.     Accurate to 1 decimal place  between +/- 9,999,999,999
  4203.     Accurate to 2 decimal places between +/-   999,999,999
  4204.     Accurate to 3 decimal places between +/-    99,999,999
  4205.     Accurate to 4 decimal places between +/-     9,999,999
  4206.     Accurate to 5 decimal places between +/-       999,999
  4207.  
  4208.     You can specify a fixed number of decimal positions in the answer by using
  4209.     the optional "fixed-decimals" value.  For example:
  4210.  
  4211.     SET z = "3.14159"
  4212.     CALCREAL x = z "+" "0" "2"      <-- This sets x to "3.14"
  4213.     CALCREAL x = z "+" "0" "4"      <-- This sets x to "3.1415"
  4214.  
  4215.     You will notice, in the second example, that no "rounding" takes place.
  4216.     The number is simply truncated at the requested decimal position.
  4217.  
  4218.     Here are some more examples of the CALCREAL command:
  4219.  
  4220.            COMMAND                                           ANSWER
  4221.            -----------------------------------------------  --------
  4222.            CALCREAL answer = "12.0"  "*"        "4.0"  "2"   "48.00"
  4223.            CALCREAL answer = "12.0"  "HIGHEST"  "4.0"  "2"   "12.00"
  4224.            CALCREAL answer =   "12"  "LOWEST      "4"  "1"     "4.0"
  4225.            CALCREAL answer =   "12"  "-"          "4"  "3"   "8.000"
  4226.            CALCREAL answer =   "12"  "+"          "4"  "1"    "16.0"
  4227.            CALCREAL answer =    "7"  "/"          "2"  "2"    "3.50"
  4228.            CALCREAL answer =    "7"  "/"          "2"          "3.5"
  4229.            CALCREAL answer =    "7"  "*"          "2"         "14.0"
  4230.  
  4231.     As shown in the examples, if you do not use the optional fixed-decimal
  4232.     value, calculations are in "floating point".  That is to say, the answer
  4233.     has as many decimal places as necessary.  (Bear in mind the accuracy
  4234.     restrictions mentioned earlier.)  Trailing zeros are removed, unless there
  4235.     are no digits after the decimal point, in which case a 0 is added.
  4236.  
  4237.  
  4238.                                 --------------------
  4239.                                 The CALCBITS Command
  4240.                                 --------------------
  4241.  
  4242.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  4243.  
  4244.     FORMAT:        CALCBITS var1 value1 operation value2
  4245.  
  4246.     PURPOSE:       CALCBITS performs logical operations
  4247.  
  4248.     SEE ALSO:      "The MakeData Command"
  4249.  
  4250.     The CALCBITS command performs "bit-wise" operations on single bytes.  The
  4251.     following operations can be performed with CALCBITS:
  4252.  
  4253.                   SYMBOL     DESCRIPTION
  4254.                   ---------  ---------------------------------
  4255.                   "AND"      value1 AND value2
  4256.                   "OR"       value1 OR  value2
  4257.                   "XOR"      value1 XOR value2
  4258.                   "SHR"      Shift value1 right by value2 bits
  4259.                   "SHL"      Shift value1 left  by value2 bits
  4260.  
  4261.     Let us say you want to strip the high bit from all of the bytes in an input
  4262.     file.  You could accomplish this with the following POM file:
  4263.  
  4264.     CHOP     1-1                    <-- Read the input file one byte at a time
  4265.     CALCBITS z $FLINE "AND" $7F     <-- Remove the high bit from the byte
  4266.     OUT      |{z}                   <-- Send the result to the output file
  4267.  
  4268.     Note that because we are reading the file one byte at a time, $FLINE is
  4269.     always one byte long.  Parse-O-Matic will terminate with an error message
  4270.     if you attempt to use CALCBITS with a value longer than one byte.  Thus,
  4271.     assuming the variable xyz contains "ABCDEF", the following line is valid:
  4272.  
  4273.     CALCBITS answer = xyz[3] "AND" $7F
  4274.  
  4275.     However, the following line would not be permitted because it refers to
  4276.     more than one byte:
  4277.  
  4278.     CALCBITS answer = xyz[3 4] "AND" $7F
  4279.  
  4280.     Here are some more examples of the CALCBITS command:
  4281.  
  4282.     COMMAND                           ANSWER   COMMENTS
  4283.     -------------------------------   ------   ------------------------------
  4284.     CALCBITS answer = $FF "AND" $7F     $7F
  4285.     CALCBITS answer = "9" "AND" $39     $39    $39 is the character "9"
  4286.     CALCBITS answer = $F0 "OR"  $0F     $FF
  4287.     CALCBITS answer = $7F "XOR" $08     $77
  4288.     CALCBITS answer = $80 "SHR" $01     $40    $80 = 10000000; $40 = 01000000
  4289.     CALCBITS answer = $01 "SHR" $01     $00    $01 = 00000001; $00 = 00000000
  4290.     CALCBITS answer = $01 "SHL" $01     $02    $01 = 00000001; $02 = 00000010
  4291.     CALCBITS answer = $80 "SHL" $01     $00    $80 = 10000000; $00 = 00000000
  4292.  
  4293.     In most of these examples, we use hex notation (e.g. $01), but you can also
  4294.     use single characters (e.g. "3" which is equivalent to $33) or decimal
  4295.     notation (e.g. #64 which is equivalent to $40).  However, you should always
  4296.     bear in mind that you are working with the underlying bit pattern.  The
  4297.     following lines are NOT equivalent:
  4298.  
  4299.     CALCBITS answer = $7F "SHL" $01         <-- Shifts left one bit
  4300.     CALCBITS answer = $7F "SHL" "1"         <-- This is not the same!
  4301.  
  4302.     The second line interprets "1" as hex $31 (decimal 49).  There is obviously
  4303.     no point in shifting an eight-bit byte 49 positions to the left.
  4304.  
  4305.  
  4306.  
  4307.     ===========================================================================
  4308.                                 INPUT PREPROCESSORS
  4309.     ===========================================================================
  4310.  
  4311.  
  4312.                                  -----------------
  4313.                                  The SPLIT Command
  4314.                                  -----------------
  4315.  
  4316.     FORMAT:  SPLIT from-position to-position [,from-pos'n to-pos'n] [...]
  4317.  
  4318.     The maximum length of an input line from a text file is 255 characters.  If
  4319.     your input file is wider than that, you must break up the file into
  4320.     manageable chunks, using the SPLIT command.  This command lets you specify
  4321.     the way in which each input line is broken up so that it will look like
  4322.     several SEPARATE lines.
  4323.  
  4324.     For example, if your input lines were up to 300 characters wide, you could
  4325.     specify:
  4326.  
  4327.     SPLIT 1 255, 256 300
  4328.  
  4329.     This breaks up each line as if it was two lines.  (If some of the lines are
  4330.     less than 256 characters, they will still be treated as two lines, although
  4331.     the second line will be null (i.e. empty).)
  4332.  
  4333.     You can specify up to 130 splits (use multiple SPLIT commands if
  4334.     necessary).  With SPLIT, Parse-O-Matic can handle large input records,
  4335.     up to a maximum total length of 32767 characters.
  4336.  
  4337.     The best way of handling SPLIT or CHOPped files is to use a combination of
  4338.     $SPLIT (explained in more detail later) and BEGIN/END.  For example:
  4339.  
  4340.     SPLIT 1 250, 251 300
  4341.     BEGIN $SPLIT = "1"
  4342.       SET a = $FLINE[ 1 10]
  4343.       SET b = $FLINE[11 20]
  4344.     END
  4345.     BEGIN $SPLIT = "2"
  4346.       SET x = $FLINE[ 1 10]
  4347.       SET y = $FLINE[11 20]
  4348.       OUTEND |{a} {b} {x} {y}
  4349.     END
  4350.  
  4351.     This outputs the data which appears (in the input file) in columns 1-10,
  4352.     11-20, 251-260 and 261-280.
  4353.  
  4354.  
  4355.                                   ----------------
  4356.                                   The CHOP Command
  4357.                                   ----------------
  4358.  
  4359.     FORMAT:        CHOP from-position to-position [,from-pos'n to-pos'n] [...]
  4360.                    CHOP 0
  4361.  
  4362.     PURPOSE:       Controls the number of bytes Parse-O-Matic will read from
  4363.                    the input file each time it processes the POM file.
  4364.  
  4365.     SEE ALSO:      "The Get Command"
  4366.  
  4367.     The CHOP command works the same way as the SPLIT command, with one
  4368.     exception:  it informs Parse-O-Matic that the input is a fixed-record-
  4369.     length file. In other words, it means that the input records are
  4370.     distinguished by having a particular (and exact) length, rather than being
  4371.     separated by end-of-line characters (Carriage Return, Linefeed) as is the
  4372.     case for a standard text file.
  4373.  
  4374.     Thus, if you have an input file containing fixed-length records, each of
  4375.     which is 200 characters wide, you could specify it like this:
  4376.  
  4377.     CHOP 1 200
  4378.  
  4379.     If the input record is more than 255 characters, you must break it up into
  4380.     smaller chunks.  For example, if the input record was 300 characters wide,
  4381.     you could break it up like this:
  4382.  
  4383.     CHOP 1 250, 251 300
  4384.  
  4385.     By using CHOP, Parse-O-Matic can handle input records up to 32767
  4386.     characters wide.  You can use the $SPLIT variable to manage your use of
  4387.     CHOP.  See the example in the section describing the SPLIT command.
  4388.  
  4389.  
  4390.     Manual Reading
  4391.     --------------
  4392.  
  4393.     There is a special form of the CHOP command, which looks like this:
  4394.  
  4395.     CHOP 0
  4396.  
  4397.     This tells Parse-O-Matic that you will handle all file reading yourself. In
  4398.     such case, $FLINE is always null.  The only way to get data from the input
  4399.     file is with the GET command.
  4400.  
  4401.     When you use CHOP 0 for manual reading, the MINLEN and READNEXT commands
  4402.     have no meaning.  If you place them in the POM file, they are ignored.
  4403.  
  4404.  
  4405.  
  4406.     ===========================================================================
  4407.                                   LOOKUP COMMANDS
  4408.     ===========================================================================
  4409.  
  4410.                                   
  4411.                                  ------------------
  4412.                                  The LOOKUP Command
  4413.                                  ------------------
  4414.  
  4415.     FORMAT:        LOOKUP var1 value1
  4416.  
  4417.     PURPOSE:       The LOOKUP command searches for value1 in a text file (the
  4418.                    name of which is specified either by the LOOKFILE command or
  4419.                    the /L startup parameter). When POM finds it, it sets var1
  4420.                    to another value found on the same line.
  4421.  
  4422.     ALTERNATIVES:  The REMAP command.
  4423.  
  4424.     Let us suppose you created a text file, named NAMES.TBL, like this:
  4425.  
  4426.     R. REAGAN        Ronald Reagan
  4427.     D. EISENHOWER    Dwight Eisenhower
  4428.     G. BUSH          George Bush
  4429.     :                :
  4430.     Column 1         Column 18
  4431.  
  4432.     This file can be used to look up a name, as in this POM file:
  4433.  
  4434.     LOOKFILE "NAMES.TBL"
  4435.     LOOKCOLS "1" "17" "18" "34"
  4436.     SET      oldname = $FLINE[21 37]
  4437.     TRIM     oldname "R" " "
  4438.     LOOKUP   newname = oldname
  4439.     OUTEND   |{oldname} {newname}
  4440.  
  4441.     The LOOKFILE command specifies the name of the look-up file.  The LOOKCOLS
  4442.     command specifies the starting and end columns for both the "text-to-look-
  4443.     for" field (known as the key field) and the "text-to-get" field (known as
  4444.     the data field).
  4445.  
  4446.     The LOOKUP command will look for oldname in NAMES.TBL.  If oldname is set
  4447.     to "G. BUSH", LOOKUP sets newname to "George Bush".  If, however, oldname
  4448.     is set to "G. WASHINGTON", which doesn't appear in NAMES.TBL, newname
  4449.     is set to "" (that is to say, an empty string).
  4450.                    
  4451.  
  4452.     Search Method
  4453.     -------------
  4454.  
  4455.     When searching for the key field, LOOKUP compares text according to the
  4456.     length of the string you are looking for.  If your LOOKUP file looks like
  4457.     this:
  4458.  
  4459.         ABCDEF    456
  4460.         ABC       678
  4461.         XYZABC    345
  4462.         XYZ       123
  4463.  
  4464.     then the command LOOKUP x = "XYZ" would match on "XYZABC".  If this search
  4465.     procedure is a problem for you, there are two ways you can deal with it:
  4466.  
  4467.     1)  Pad your search strings before searching, as in this example:
  4468.  
  4469.         PAD     search "R" " " "6"
  4470.         LOOKUP  x = search
  4471.  
  4472.         If the search variable was original set to "XYZ", the PAD command
  4473.         would set it to "XYZ   ", which would not match XYZABC.
  4474.  
  4475.     2)  Put the shorter key fields in the lookup file ahead of the longer
  4476.         ones (of which they are a sub-string), as in this example:
  4477.  
  4478.         ABC       678
  4479.         ABCDEF    456
  4480.         XYZ       123
  4481.         XYZABC    345
  4482.  
  4483.         It is worth pointing out that this look-up file is sorted in
  4484.         ASCII order (whereas the example given earlier was not).  A sorted
  4485.         file can be more efficient, as explained in "The LookSpec Command".
  4486.  
  4487.  
  4488.     Limitations
  4489.     -----------
  4490.  
  4491.     There is no limit to the number of lines that you can put in a look-up
  4492.     file.  However, the more lines there are, the longer it will take to
  4493.     process (because there is more to search).  The maximum length of a line
  4494.     in a look-up file is 255 characters.
  4495.  
  4496.  
  4497.     Null Lines and Comments
  4498.     -----------------------
  4499.  
  4500.     In the look-up file, null (empty) lines are ignored.  You can also include
  4501.     comments in the file by starting the line with a semi-colon:
  4502.  
  4503.     ; Some of the Presidents of the United States
  4504.     R. REAGAN        Ronald Reagan
  4505.     D. EISENHOWER    Dwight Eisenhower
  4506.     G. BUSH          George Bush
  4507.  
  4508.     The LOOKUP command can be used for more than just names, of course.  You
  4509.     could use it to look up prices, phone numbers, addresses and so on.
  4510.  
  4511.  
  4512.     Multiple Columns
  4513.     ----------------
  4514.  
  4515.     You can use the same lookup file to find different items that are related
  4516.     to the same key field.  For example, let's say you have created a lookup
  4517.     file, named EMPLOYEE.TBL, which looks like this:
  4518.  
  4519.     ; EMPLOYEE#   NAME           PHONE
  4520.       00001       John Smith     555-1212
  4521.       00002       Mary Jones     555-2121
  4522.       00003       Fred Johnson   555-1122
  4523.  
  4524.     You could look up an employee's name and phone number as follows:
  4525.  
  4526.     LOOKFILE "EMPLOYEE.TBL"
  4527.     LOOKCOLS "3" "7" "15" "37"
  4528.     LOOKSPEC "N" "Y" "N"
  4529.     LOOKUP   empdata = "00002"
  4530.     SET      name  = empdata[ 1 12]
  4531.     SET      phone = empdata[16 23]
  4532.     TRIM     name  "B" " "
  4533.     TRIM     phone "B" " "
  4534.  
  4535.     You could, of course, specify a different LOOKCOLS prior to each LOOKUP,
  4536.     but that would mean reading the disk twice.  It most cases, it is faster
  4537.     to obtain the data all at once, then extract it.
  4538.  
  4539.  
  4540.     LOOKUP Versus REMAP
  4541.     -------------------
  4542.  
  4543.     If you have only a few thousand bytes of lookup data, you might be able to
  4544.     use the REMAP command instead of LOOKUP.  However, you can not simply
  4545.     replace LOOKFILE and LOOKUP with MAPFILE and REMAP.  REMAP does not return
  4546.     a null value if it can not find the item being sought, so you will have to
  4547.     change your POM file to compare the original string with the revised
  4548.     string, in order to see if it has changed (i.e. it was found).  Even with
  4549.     this test, REMAP might "fool you" if it finds a partial match.
  4550.  
  4551.     If you are processing a lot of input data, using REMAP may speed up
  4552.     processing, since REMAP works in RAM memory, while LOOKUP reads the disk.
  4553.     However, if your disk uses "caching", the performance improvement may be
  4554.     negligible.
  4555.  
  4556.  
  4557.                                 --------------------
  4558.                                 The LOOKFILE Command
  4559.                                 --------------------
  4560.  
  4561.     FORMAT:        LOOKFILE value1
  4562.  
  4563.     PURPOSE:       The LOOKFILE command specifies the name of the look-up file
  4564.                    for the next LOOKUP command.
  4565.  
  4566.     SEE ALSO:      "How Parse-O-Matic Searches for a File"
  4567.  
  4568.     LOOKFILE lets you use several look-up files in one POM file. For example:
  4569.  
  4570.     SET name = $FLINE[1 20]
  4571.     ; Look up full name
  4572.     LOOKFILE "NAMES.TBL"
  4573.     LOOKCOLS "1" "25" "30" "50"
  4574.     LOOKUP   fullname = name
  4575.     ; Look up phone number
  4576.     LOOKFILE "PHONE.TBL"
  4577.     LOOKCOLS "1" "25" "30" "40"
  4578.     LOOKUP   phone = name
  4579.     ; Output result
  4580.     OUTEND   |{name} {fullname} {newname}
  4581.  
  4582.     If you only have one look-up file, you may omit the LOOKFILE command and
  4583.     specify the file name on the command line, using the /L parameter.  For
  4584.     example, you could write a POM file like this:
  4585.  
  4586.     SET name = $FLINE[1 20]
  4587.     ; Look up full name
  4588.     LOOKCOLS "1" "25" "30" "50"
  4589.     LOOKUP   fullname = name
  4590.     ; Output result
  4591.     OUTEND   |{name} {fullname}
  4592.  
  4593.     Your POM command could then look like this:
  4594.  
  4595.     POM MYPOM.POM INPUT.TXT OUTPUT.TXT /LC:\MYFILES\NAMES.TBL
  4596.  
  4597.     This technique allows you to use several different look-up files with the
  4598.     same POM file, simply by changing the command line.  (The method by which
  4599.     Parse-O-Matic finds the file is discussed in the section "How Parse-O-Matic
  4600.     Searches for a File".)
  4601.  
  4602.     The longest line allowed in a look-up file is 255 characters long.
  4603.  
  4604.  
  4605.                                 --------------------
  4606.                                 The LOOKCOLS Command
  4607.                                 --------------------
  4608.  
  4609.     FORMAT:        LOOKCOLS value1 value2 value3 value4
  4610.  
  4611.     PURPOSE:       The LOOKCOLS command specifies the starting and ending
  4612.                    columns for the key and data fields in a look-up file (see
  4613.                    the explanation of the LOOKUP command for an overview of
  4614.                    look-up files).
  4615.  
  4616.     PARAMETERS:    value1 specifies the starting column for the key  field
  4617.                    value2 specified the  ending  column for the key  field
  4618.                    value3 specifies the starting column for the data field
  4619.                    value4 specified the  ending  column for the data field
  4620.  
  4621.     NUMERICS:      Tabs, spaces and commas are stripped from value1, 2, 3 and 4
  4622.  
  4623.     You can specify a null value to indicate "same as last time".  For example:
  4624.  
  4625.     SET name = $FLINE[1 20]
  4626.     LOOKFILE "NAMES.TBL"
  4627.     LOOKCOLS "1" "25" "30" "50"
  4628.     LOOKUP   fullname = name
  4629.     LOOKFILE "PHONE.TBL"
  4630.     LOOKCOLS "" "" "" "40"
  4631.     LOOKUP   phonenum = name
  4632.     OUTEND   |{name} {fullname} {phonenum}
  4633.  
  4634.     The second LOOKCOLS command uses the same numbers for the first three
  4635.     values that the first LOOKCOLS command used.
  4636.  
  4637.     If you do not specify a LOOKCOLS command, the default values are:
  4638.  
  4639.     Key Field:   Starting column  =   1
  4640.                  Ending column    =  10
  4641.     Data Field:  Starting column  =  12
  4642.                  Ending column    = 255
  4643.  
  4644.     This is equivalent to LOOKCOLS "1" "10" "12" "255".
  4645.  
  4646.  
  4647.                                 --------------------
  4648.                                 The LOOKSPEC Command
  4649.                                 --------------------
  4650.  
  4651.     FORMAT:        LOOKSPEC value1 value2 value3
  4652.  
  4653.     PURPOSE:       The LOOKSPEC command configures the way the next LOOKUP
  4654.                    command will work.
  4655.  
  4656.     PARAMETERS:    value1 = Trim           ("Y" or "N" -- default "Y")
  4657.                    value2 = Sorted         ("Y" or "N" -- default "N")
  4658.                    value3 = Case-sensitive ("Y" or "N" -- default "N")
  4659.  
  4660.     The Trim setting specifies whether or not the data field should have spaces
  4661.     stripped off both ends.
  4662.  
  4663.     The Sorted setting specifies whether or not the look-up file is sorted by
  4664.     the key field.  A sorted file is much faster than an unsorted file.  This
  4665.     is especially noticeable if you have a large look-up file and a lot of
  4666.     input to process.
  4667.  
  4668.     The Case-sensitive setting specifies whether or not LOOKUP should distin-
  4669.     guish between upper and lower case when searching.  The default setting is
  4670.     "N" (No), so that LOOKUP would find "John Smith", even if it appeared in
  4671.     the look-up file as "JOHN SMITH".  It is usually safest to set Case-
  4672.     sensitivity to "N", but if you set it to "Y", searching is slightly faster.
  4673.  
  4674.     You can specify a null value to indicate "same as last time".  For example:
  4675.  
  4676.     SET name = $FLINE[1 20]
  4677.     LOOKFILE "DATA.TBL"
  4678.     LOOKCOLS "1" "25" "30" "50"
  4679.     LOOKSPEC "Y" "Y" "Y"
  4680.     LOOKUP   fullname = name
  4681.     LOOKCOLS "" "" "60" "70"
  4682.     LOOKSPEC "N" "" ""
  4683.     LOOKUP   phonenum = name
  4684.     OUTEND   |{name} {fullname} {phonenum}
  4685.  
  4686.     The second LOOKSPEC command uses the same settings for Sorted and Case-
  4687.     sensitivity as the first one, but specifies a different Trim setting.
  4688.  
  4689.  
  4690.  
  4691.     ===========================================================================
  4692.                                   DATA CONVERTERS
  4693.     ===========================================================================
  4694.  
  4695.  
  4696.                                 --------------------
  4697.                                 The MAKEDATA Command
  4698.                                 --------------------
  4699.  
  4700.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  4701.  
  4702.     FORMAT:        MAKEDATA var1 value1 value2
  4703.  
  4704.     PURPOSE:       MAKEDATA converts text data into a binary format.
  4705.  
  4706.     PARAMETERS:    var1     is the variable being set
  4707.                    value1   is the text data you want to convert
  4708.                    value2   is the predefined data type you want to create
  4709.  
  4710.     NUMERICS:      Tabs, spaces and commas are stripped from value1, if it is
  4711.                    numeric (as indicated by value2)
  4712.  
  4713.     SEE ALSO:      "Predefined Data Types" and "The CalcBits Command"
  4714.  
  4715.     When you are writing to a binary file (using the OUT command), you often
  4716.     need to convert text information to a binary representation.  MAKEDATA
  4717.     recognizes many standard data formats (see "Predefined Data Types").
  4718.  
  4719.  
  4720.     Creating Binary Data
  4721.     --------------------
  4722.  
  4723.     Let us say you have a four-line text file that looks like this:
  4724.  
  4725.      1234
  4726.      -456
  4727.        23
  4728.     90211
  4729.  
  4730.     Here is a POM file that reads the numbers from the file, then outputs them
  4731.     in binary format, as 16-bit signed integers:
  4732.  
  4733.     MAKEDATA z $FLINE "INTEGER"    <-- Convert the number to an integer
  4734.     OUT      |{z}                  <-- Send the integer to the output file
  4735.  
  4736.     We use OUT instead of OUTEND, since OUTEND would put an end-of-line
  4737.     (Carriage Return, Line Feed) after the data.
  4738.  
  4739.     If the POM file shown in the example was run with the input data shown,
  4740.     it would create an output file containing four integers.  In other words,
  4741.     the file would be eight bytes long (four integers of two bytes each).
  4742.  
  4743.  
  4744.     Converting Dates
  4745.     ----------------
  4746.  
  4747.     In some files, a date serial number (see "The ZeroDate Command") might be
  4748.     represented by a numeric format such as INTEGER or LONGINT.  To write a
  4749.     date serial number to the output file, you must first convert the date with
  4750.     MAKEDATA, then use MAKEDATA again to convert the resulting number to the
  4751.     appropriate data type.
  4752.  
  4753.     The value1 part of the MAKEDATA must be in a precise format:
  4754.  
  4755.     "YYYY [M]M [D]D"               <-- Square brackets indicate optional digits
  4756.  
  4757.     That is to say:
  4758.  
  4759.     1) A four-digit year
  4760.     2) A space
  4761.     3) A one or two digit month (January = 1 or 01, December = 12)
  4762.     4) A space
  4763.     5) A one or two digit day of the month (e.g. 1 or 01 or 31)
  4764.  
  4765.     You can assemble the date string from various other data, using the
  4766.     DATE command.  Let us say you have a one-line text file that contains
  4767.     the date in Month-Day-Year format:
  4768.  
  4769.     01-01-2001
  4770.  
  4771.     You can read this file and output a date serial number as a long integer
  4772.     (LONGINT) with the following POM file:
  4773.  
  4774.     ZERODATE "2000" "1" "1"                <-- Set "day zero"
  4775.     SET      year  = $FLINE[7 10]          <-- Get the year
  4776.     SET      month = $FLINE[1  2]          <-- Get the month
  4777.     SET      day   = $FLINE[4  5]          <-- Get the day of the month
  4778.     DATE     x year month day "Y ?n ?d"    <-- Set x to "2001 01 01"
  4779.     MAKETEXT y x "DATE"                    <-- Set y to "366"
  4780.     MAKEDATA z y "LONGINT"                 <-- Set z to a long integer
  4781.     OUT      |{z}                          <-- Place it in the output file
  4782.  
  4783.     A typical problem with date data is that the year does not include
  4784.     the first two digits (e.g. you have "97" instead of "1997").  In
  4785.     such cases, your POM file has to make a decision as to which century
  4786.     the date belongs to.  Here is one way to handle this situation:
  4787.  
  4788.     BEGIN year #>= "50"
  4789.       CALC year = year + "1900"
  4790.     ELSE
  4791.       CALC year = year + "2000"
  4792.     END
  4793.  
  4794.     This works around the problem as follows:
  4795.  
  4796.             Any year between     is placed in         Examples
  4797.             ----------------     ----------------     --------------
  4798.             "50" and "99"        the 20th century     "1950"  "1999"
  4799.             "00" and "49"        the 21st century     "2000"  "2049"
  4800.  
  4801.     You have to be careful when choosing the "cut-off date" (1950, in the
  4802.     example above).  You should make your decision only after studying your
  4803.     input data carefully.
  4804.  
  4805.  
  4806.     Practical Considerations
  4807.     ------------------------
  4808.  
  4809.     The examples shown here assume that your input file contains only one kind
  4810.     of data.  In most cases, you will use the CHOP command to obtain complete
  4811.     data records of fixed length, then use SET to extract portions thereof.
  4812.     If you are reading a file with variable-length records, you can use CHOP 0
  4813.     (manual reading) and the GET command.
  4814.  
  4815.  
  4816.                                 --------------------
  4817.                                 The MAKETEXT Command
  4818.                                 --------------------
  4819.  
  4820.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  4821.  
  4822.     FORMAT:        MAKETEXT var1 value1 value2
  4823.  
  4824.     PURPOSE:       MAKETEXT converts binary data into text format.
  4825.  
  4826.     PARAMETERS:    var1     is the variable being set
  4827.                    value1   is the data you want to convert
  4828.                    value2   is the predefined data type of value1
  4829.  
  4830.     NOTES:         value1 is normally in binary (i.e. it looks like "garbage
  4831.                    characters" if you output it to a text file).  However, if
  4832.                    value2 specifies the DATE data type, value1 must be in text
  4833.                    form (e.g. "1234").  The reason for this difference is
  4834.                    described in the "Converting Dates" section below.
  4835.  
  4836.     SEE ALSO:      "Predefined Data Types"
  4837.  
  4838.     When reading a binary file (using the CHOP command), you often need to
  4839.     convert binary information to a text representation. MAKETEXT recognizes
  4840.     many standard data formats (see "Predefined Data Types").
  4841.  
  4842.  
  4843.     Converting Binary Data
  4844.     ----------------------
  4845.  
  4846.     Let us say you have a binary file that contains several WORD values
  4847.     (unsigned integers, each of which is 2 bytes long).  You can read and
  4848.     decode them with the following POM file:
  4849.  
  4850.     CHOP 1-2                            <-- Read the file two bytes at a time
  4851.     MAKETEXT x $FLINE "WORD"            <-- Convert the WORD to text format
  4852.     OUTEND   |{x}                       <-- Output the data to a text file
  4853.  
  4854.  
  4855.     Converting Dates
  4856.     ----------------
  4857.  
  4858.     MAKETEXT can convert a date serial number (see "The ZeroDate Command") to
  4859.     a formatted date.  Since there is no standard data format for date serial
  4860.     numbers, you must use MAKETEXT to convert the number into text form, and
  4861.     then use MAKETEXT again to format the date.
  4862.  
  4863.     Let us say you have a binary file that contains dates, represented as
  4864.     LONGINTs (4-byte signed integers).  You could convert them to dates with
  4865.     the following POM file:
  4866.  
  4867.     CHOP 1-4                     <-- Read 4 bytes at a time
  4868.     ZERODATE "1936" "1" "1"      <-- Set the "zero date"
  4869.     MAKETEXT x $FLINE "LONGINT"  <-- Convert the binary data to a text number
  4870.     MAKETEXT y x "DATE Y-M-?d"   <-- Convert to text date (e.g. "1998-JUL-01")
  4871.     OUTEND   |{y}                <-- Output the date to a text file
  4872.  
  4873.  
  4874.     Practical Considerations
  4875.     ------------------------
  4876.  
  4877.     The examples shown here assume that your input file contains only one kind
  4878.     of data.  In most cases, you will use the CHOP command to obtain complete
  4879.     data records of fixed length, then use SET to extract portions thereof.
  4880.     If you are reading a file with variable-length records, you can use CHOP 0
  4881.     (manual reading) and the GET command.
  4882.  
  4883.  
  4884.  
  4885.     ===========================================================================
  4886.                                MISCELLANEOUS COMMANDS
  4887.     ===========================================================================
  4888.  
  4889.  
  4890.                                  -----------------
  4891.                                  The ERASE Command
  4892.                                  -----------------
  4893.  
  4894.     FORMAT:        ERASE value1
  4895.  
  4896.     PURPOSE:       Deletes a file (if it exists).
  4897.  
  4898.     PARAMETERS:    value1 is the name of the file to be deleted
  4899.  
  4900.     SEE ALSO:      "Long File Names in Win95"
  4901.  
  4902.     Here is an example of the ERASE command:
  4903.  
  4904.     ERASE "C:\XYZ.TXT"
  4905.  
  4906.     This will delete the file C:\XYZ.TXT if it exists.  If it does not exist,
  4907.     nothing is done.
  4908.  
  4909.     You can not delete the current input file, output file, trace file or
  4910.     lookup file.  If you attempt to do so, Parse-O-Matic will terminate with
  4911.     an error.
  4912.  
  4913.     You can not delete a device (e.g. ERASE "LPT1:").  The ERASE command
  4914.     simply ignores such requests.
  4915.  
  4916.     If value1 is preceded by a "+" character, the plus sign is ignored.
  4917.     See "How Parse-O-Matic Opens an Output File" for an explanation of the
  4918.     significance of the plus sign.
  4919.  
  4920.  
  4921.                                  ------------------
  4922.                                  The GETENV Command
  4923.                                  ------------------
  4924.  
  4925.     FORMAT:        GETENV var1 value1
  4926.  
  4927.     PURPOSE:       GETENV obtains a system environment variable
  4928.  
  4929.     PARAMETERS:    var1   is the variable being set
  4930.                    value1 is the name of the system environment variable
  4931.  
  4932.     NOTES:         System environment variables are sometimes referred to as
  4933.                    "DOS Environment Variables" or "SET Variables".
  4934.  
  4935.     SEE ALSO:      Explanations of the SET & PATH commands in your DOS manual,
  4936.                    or "The Environment Area" in your Windows or OS/2 manual.
  4937.  
  4938.     GETENV enables you to access certain important settings that concern your
  4939.     computer's operating system.  To see what settings are available, enter the
  4940.     following command at the DOS prompt:
  4941.  
  4942.     SET
  4943.  
  4944.     This will display the contents of your computer's "environment area".  Two
  4945.     of the most important values in the environment area are COMSPEC and PATH.
  4946.     These are briefly described later, but refer to your operating system
  4947.     manual for full details.
  4948.  
  4949.     GETENV removes all spaces, tabs and equals-signs ("=") from value1,
  4950.     converts it to uppercase, then looks it up in the system environment area.
  4951.  
  4952.     - If it finds it, var1 is set to the corresponding value.
  4953.     - If it does not find it, var1 is set to an empty (null) string.
  4954.  
  4955.  
  4956.     Disappearing Environment Variables
  4957.     ----------------------------------
  4958.  
  4959.     Sometimes an environment variable disappears for no apparent reason.  There
  4960.     are two likely reasons for this:
  4961.  
  4962.     1)  You ran out of environment space.
  4963.  
  4964.         There is only a limited amount of room in the system environment area
  4965.         (which is located in RAM memory).  If you think this is the problem,
  4966.         type your DOS SET command to save a variable into the system
  4967.         environment, then type SET by itself to review the contents of the
  4968.         environment.  If your variable does not appear, consult your operating
  4969.         system manual to find out how to expand your environment space.
  4970.  
  4971.     2)  It was set by a COPY of the operating system.
  4972.  
  4973.         If you are in Windows and you run DOS, then use the DOS SET command, it
  4974.         will only affect the environment area associated with the copy of DOS
  4975.         that you are running.  When you exit this copy and start up another
  4976.         one, it will not contain the variable.  You can address this problem by
  4977.         setting the variable in your AUTOEXEC.BAT file, or by running a batch
  4978.         file that sets the variable before running Parse-O-Matic.
  4979.  
  4980.  
  4981.     Examples
  4982.     --------
  4983.  
  4984.     The following command will determine which directories get searched when
  4985.     you are looking for a program or a file:
  4986.  
  4987.     GETENV path "PATH"
  4988.  
  4989.     To find out the name of your command interpreter (usually COMMAND.COM)
  4990.     and where it is located, try this command:
  4991.  
  4992.     GETENV comspec "COMSPEC"
  4993.  
  4994.     You can use GETENV as a simple "input routine" for Parse-O-Matic
  4995.     applications.  For details, see "Controlling a POM File from the Command
  4996.     Line", in the section entitled "Effective Use of Batch Files".
  4997.  
  4998.  
  4999.                                   ---------------
  5000.                                   The LOG Command
  5001.                                   ---------------
  5002.  
  5003.     FORMAT:        LOG value1 [comparator] value2 value3 [value4 [value5]]
  5004.  
  5005.     PURPOSE:       LOG places a message (value3) in the processing log file
  5006.                    (POMLOG.TXT) if the comparison is true.  Both value4 and
  5007.                    value5 are optional; if they are present, they are added
  5008.                    to end of value3.
  5009.  
  5010.     NOTES:         The processing log is described in the section "Logging".
  5011.  
  5012.     Here is an example of the LOG command:
  5013.  
  5014.     SET   emplnumb = $FLINE[ 1  9]
  5015.     SET   sales    = $FLINE[10 20]
  5016.     TRIM  sales "B" " "
  5017.     LOG   sales = "0" "WARNING!  Zero sales for employee number:"
  5018.     LOG   sales = "0" emplnumb
  5019.  
  5020.     This adds two warning lines to the processing log if the sales figures is
  5021.     zero.
  5022.  
  5023.     The logging feature lets you run Parse-O-Matic unattended, then come back
  5024.     later to review (via the processing log) any exceptional conditions.  For
  5025.     some additional comments on logging, see "Unattended Operation".
  5026.  
  5027.     The maximum length of a LOG string (value3, plus value4 and value5 if
  5028.     present) is 245 characters.
  5029.  
  5030.  
  5031.                                 -------------------
  5032.                                 The MSGWAIT Command
  5033.                                 -------------------
  5034.  
  5035.     FORMAT:        MSGWAIT value1
  5036.  
  5037.     PURPOSE:       MSGWAIT controls the amount of time that a processing error
  5038.                    message appears on the screen before it times out. (Messages
  5039.                    from the HALT command are treated as error messages.)
  5040.  
  5041.     PARAMETERS:    value1 is the delay time in seconds
  5042.  
  5043.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  5044.  
  5045.     DEFAULTS:      If the MSGWAIT command is not included in the POM file, and
  5046.                    an error occurs, Parse-O-Matic will wait until you press a
  5047.                    key; the message will not time out.
  5048.  
  5049.     NOTES:         If value1 is "0", error messages will not time out.
  5050.                    The maximum value for value1 is 60000 (about 16 hours).
  5051.                    You can set value1 to "1", but one second is usually too
  5052.                    short a delay; a value of "60" (one minute) is better.
  5053.  
  5054.     SEE ALSO:      "The Halt Command", "Unattended Operation", "Quiet Mode"
  5055.  
  5056.     The MSGWAIT command lets you control the behaviour of error messages that
  5057.     appear during the processing of an input file.  This is helpful if you
  5058.     have created POM applications that are run unattended.
  5059.  
  5060.     If Parse-O-Matic was invoked by a batch file or application program, you
  5061.     want may error messages to "time out", allowing Parse-O-Matic to terminate,
  5062.     and processing to continue.
  5063.  
  5064.  
  5065.     Standard Behaviour
  5066.     ------------------
  5067.  
  5068.     If Parse-O-Matic encounters an error while reading in a POM file (i.e.
  5069.     during the "compile" step), it displays a message on the screen and waits
  5070.     until you press a key.  Parse-O-Matic then terminates.
  5071.  
  5072.     When running the actual POM file (i.e. while processing the input file),
  5073.     Parse-O-Matic will normally behave the same way:  if an error occurs (or
  5074.     if a HALT command is encountered), it will display a message on the screen
  5075.     and wait for you to press a key before it terminates.
  5076.  
  5077.  
  5078.     Setting a Time-Out Delay
  5079.     ------------------------
  5080.  
  5081.     You can use the MSGWAIT command to tell Parse-O-Matic to continue ("time
  5082.     out") after a certain number of seconds.  For example:
  5083.  
  5084.     MSGWAIT "60"
  5085.  
  5086.     This tells Parse-O-Matic to wait about 60 seconds if an error is
  5087.     encountered while processing the input file.  Parse-O-Matic will then
  5088.     terminate.  (The actual delay depends on the type of computer you are
  5089.     using; a delay of "60" will typically last between 55 and 65 seconds).
  5090.  
  5091.  
  5092.     Color Cues
  5093.     ----------
  5094.  
  5095.     If you have a color monitor, you can tell if a message will "time out"
  5096.     by the color of the "Press a key to continue" prompt:
  5097.  
  5098.     - If it is magenta (sometimes called "purple") it will NOT time out
  5099.     - If it is blue, if WILL time out
  5100.  
  5101.  
  5102.     Key Stacking
  5103.     ------------
  5104.  
  5105.     To ensure that an error message is not inadvertently bypassed, "stacked"
  5106.     keystrokes are ignored by Parse-O-Matic.  That is to say, if you press
  5107.     several keys before an error message is displayed, Parse-O-Matic gets rid
  5108.     of them before displaying the message.
  5109.  
  5110.  
  5111.     Exceptions
  5112.     ----------
  5113.  
  5114.     If Parse-O-Matic is processing an empty input file, it will display the
  5115.     warning "Input file is empty", then continue processing the POM file when
  5116.     you press a key, or after a delay of about 60 seconds.
  5117.  
  5118.     The MSGWAIT command does not affect messages that report errors detected
  5119.     during the compilation (initial read-in) of the POM file.
  5120.  
  5121.     The MSGWAIT command does not affect the "Retry or Cancel" message that
  5122.     appears if you are dealing with a device (see "Sending Output to a
  5123.     Device").
  5124.  
  5125.  
  5126.     A Word of Caution
  5127.     -----------------
  5128.  
  5129.     A POM file should be thoroughly tested before setting the MSGWAIT time to a
  5130.     value other than "0".  Most error messages are serious enough to justify
  5131.     waiting until the user acknowledges them.
  5132.  
  5133.     If you call Parse-O-Matic from a batch file or application program, you can
  5134.     check the success of the parsing job by checking the return code.  (See
  5135.     "Effective Use of Batch Files" and "Running Parse-O-Matic from Another
  5136.     Program").
  5137.  
  5138.     If there was a processing error and you did not check the parsing job
  5139.     (either by testing the program return code, or by consulting the
  5140.     processing log), the resulting oversight could be serious.
  5141.  
  5142.  
  5143.                                  -----------------
  5144.                                  The PAUSE Command
  5145.                                  -----------------
  5146.  
  5147.     FORMAT:        PAUSE value1
  5148.  
  5149.     PURPOSE:       Delays the specified number of milliseconds
  5150.  
  5151.     PARAMETERS:    value1 is the delay time (between 1 and 65500)
  5152.  
  5153.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  5154.  
  5155.     NOTES:         1     millisecond  = One thousandth of a second
  5156.                    100   milliseconds = One tenth of a second
  5157.                    1000  milliseconds = One second
  5158.                    60000 milliseconds = One minute
  5159.  
  5160.     Here are some typical applications of the PAUSE command:
  5161.  
  5162.     - Slow down Parse-O-Matic so you can watch the processing screen
  5163.     - Give a slow laser printer extra time to eject a page after an OUTPAGE
  5164.     - Give you time to remove a page from a dot-matrix printer after an OUTPAGE
  5165.     - Give a communications device time to complete its current operation
  5166.  
  5167.     Here is an example of the latter application:
  5168.  
  5169.     OFILE  "COM1:"             <-- Direct output to the modem on COM1
  5170.     OUTEND |ATZ                <-- Send a modem initialization command
  5171.     PAUSE  "1000"              <-- Wait one second for the command to complete
  5172.     OUTEND |ATDT555-1234       <-- Send a dialing command to the modem
  5173.  
  5174.     If your PAUSE command is 200 milliseconds or longer, Parse-O-Matic displays
  5175.     a "PAUSED" message in the lower right corner of the processing screen.
  5176.     While this appears, you can press any key to end the pause.  (We recommend
  5177.     that you use the spacebar -- and avoid the Esc key.  Parse-O-Matic
  5178.     processing will be terminated if the PAUSE happens to end at the precise
  5179.     moment your finger is coming down on the Esc key!)
  5180.  
  5181.  
  5182.                                  -----------------
  5183.                                  The SOUND Command
  5184.                                  -----------------
  5185.  
  5186.     FORMAT:        SOUND value
  5187.  
  5188.     PURPOSE:       The SOUND command performs two functions:
  5189.                    1)  It makes a noise, or ...
  5190.                    2)  It sets the noise made when an error occurs
  5191.  
  5192.     The SOUND command has a repetoire of nine distinctive noises:
  5193.  
  5194.     BEEP BIP BUZZ EDGE ERROR HUH PIP TRILL WHOOP
  5195.  
  5196.     These sounds are useful for alerting you to unusual situations.  Let's say
  5197.     you wanted to be warned if one of the fields in a file comes up blank.  You
  5198.     could write the code this way:
  5199.  
  5200.     BEGIN lastname = ""
  5201.       SOUND "WHOOP"
  5202.       SET   lastname = "?"
  5203.     END
  5204.  
  5205.     Case is not important; the following commands are all equivalent:
  5206.  
  5207.     SOUND "WHOOP"
  5208.     SOUND "Whoop"
  5209.     SOUND "whoop"
  5210.  
  5211.  
  5212.     The LISTEN Utility
  5213.     ------------------
  5214.  
  5215.     You can listen to any given sound by using the LISTEN command at the DOS
  5216.     prompt.  To hear what TRILL sounds like, enter this command:
  5217.  
  5218.     LISTEN trill
  5219.  
  5220.     By default, Parse-O-Matic error messages will alert you by playing the
  5221.     ERROR sound.  To hear this sound, enter the following command at the DOS
  5222.     prompt:
  5223.  
  5224.     LISTEN error
  5225.  
  5226.  
  5227.     Changing the Error Message Sound
  5228.     --------------------------------
  5229.  
  5230.     If you find the error message sound noise annoying, you can replace it with
  5231.     one of the other sounds by using the special ERRMSG specification of the
  5232.     SOUND command.  For example, to replace the ERROR sound with the BUZZ
  5233.     sound, place this line at the top of your POM file:
  5234.  
  5235.     SOUND "ERRMSG BUZZ"
  5236.  
  5237.     If you don't want any sound made when an error occurs, use this command:
  5238.  
  5239.     SOUND "ERRMSG QUIET"
  5240.  
  5241.     The ERRMSG specification will only affect errors generated during the
  5242.     actual running of the POM file.  If an error is encountered while
  5243.     Parse-O-Matic is compiling the POM file, it will use the ERROR sound
  5244.     when it reports the problem.
  5245.  
  5246.  
  5247.                                  -----------------
  5248.                                  The TRACE Command
  5249.                                  -----------------
  5250.  
  5251.     FORMAT:        TRACE var1
  5252.  
  5253.     PURPOSE:       The TRACE command is an alternative to standard tracing (see
  5254.                    "Tracing", in the "Techniques" section).
  5255.  
  5256.     PARAMETERS:    var1 is the variable being traced.
  5257.  
  5258.     When you include a TRACE command in your POM file, Parse-O-Matic will
  5259.     create a text file, named POM.TRC, and use it to keep a detailed record of
  5260.     POM's processing.  Here is an example of the TRACE command:
  5261.  
  5262.     TRACE PRICE
  5263.  
  5264.     This traces the variable named "PRICE".  After processing, the file POM.TRC
  5265.     will show everything that happened, and give the value of PRICE at the
  5266.     TRACE line.
  5267.  
  5268.     NOTE:  Since trace files are so detailed, they can be very large.  If you
  5269.     are trying to debug a POM file using TRACE, it is a good idea to use a
  5270.     small input file.
  5271.  
  5272.  
  5273.  
  5274.     ===========================================================================
  5275.                                        TERMS
  5276.     ===========================================================================
  5277.  
  5278.  
  5279.                                        ------
  5280.                                        Values
  5281.                                        ------
  5282.  
  5283.     A value can be specified in the following ways:
  5284.  
  5285.     "text"             A literal text string
  5286.     #number            An ASCII character, in decimal (e.g. #32 = Space)
  5287.     #number#number...  Several ASCII characters (e.g. #32#32 = 2 Spaces)
  5288.     $xx                A byte, in hexadecimal (e.g. $2F = decimal 47)
  5289.     $xx$xx...          Several hex bytes ($ff$ff = binary 1111111111111111)
  5290.     VARNAME            The name of a variable
  5291.     VARNAME[start end] A substring of a variable
  5292.     VARNAME[start]     A single character
  5293.     VARNAME+           Inline incremented variable (explained below)
  5294.     VARNAME-           Inline decremented variable (explained below)
  5295.  
  5296.     Variable names can be up to 12 characters long.  There is no distinction
  5297.     between upper and lower case in the variable name.  A POM file can contain
  5298.     about 1000 variables and literals.
  5299.  
  5300.     The # character is used to specify a literal text string of one or more
  5301.     characters.  Follow each # with the decimal value of the ASCII character
  5302.     you want.  Here are some useful values:
  5303.  
  5304.            #10 = Line Feed   #12 = Form Feed   #13 = Carriage Return
  5305.  
  5306.     Parse-O-Matic predefines several variables.  They are:
  5307.  
  5308.     $FLINE   = The line just read from the file (max. length 255 chars)
  5309.     $FLUPC   = The line just read from the file, in uppercase
  5310.     $BRL     = The { character (used in OUT)
  5311.     $BRR     = The } character (used in OUT)
  5312.     $COMMAND = The current POM command line (see "POM and Wildcards")
  5313.     $SPLIT   = The CHOP or SPLIT number you are currently processing
  5314.     $TAB     = The tab character (Hex $09; ASCII 09)
  5315.  
  5316.     Although these predefined variables start with a dollar sign ($), it does
  5317.     not mean they are in some way "hexadecimal" (as in the case of the hex
  5318.     values mentioned earlier).  In this case, the $ character is simply a means
  5319.     to indicate that the variables are defined by Parse-O-Matic.  In general,
  5320.     you should avoid creating variables that start with anything but a letter.
  5321.  
  5322.     Since $FLINE has a maximum length of 255 characters, you will have to use
  5323.     the SPLIT or CHOP command if your input file is wider than that.  The
  5324.     $SPLIT variable reports which segment you are processing.  For example,
  5325.     if you had this command...
  5326.  
  5327.     CHOP 1 255, 256 380
  5328.  
  5329.     then $SPLIT would be set to "1" when it was processing columns 1 to 255,
  5330.     and it would be set to "2" when it was processing columns 256 to 380.
  5331.  
  5332.  
  5333.                                      ----------
  5334.                                      Delimiters
  5335.                                      ----------
  5336.  
  5337.     If you need to specify a quotation mark, use "".  For example:
  5338.  
  5339.     IGNORE $FLINE = "He said ""Hello"" to me."
  5340.  
  5341.     This ignores any line containing:  He said "Hello" to me.
  5342.  
  5343.  
  5344.                                  ------------------
  5345.                                  Illegal Characters
  5346.                                  ------------------
  5347.  
  5348.     No POM command can contain these ASCII characters:
  5349.  
  5350.                          HEX    DECIMAL  NAME
  5351.                        -------  -------  --------------------
  5352.                          $00      #00    NULL
  5353.                          $0A      #10    LF (Linefeed)
  5354.                          $0D      #13    CR (Carriage Return)
  5355.  
  5356.     Of course, LF and CR do appear at the end of each line in the POM file,
  5357.     which is a text file.  If you have to specify these characters in a POM
  5358.     command, use either the $ or # character to denote hex or decimal literals
  5359.     (e.g. SET linefeed = $0A).
  5360.  
  5361.  
  5362.                                  -----------------
  5363.                                  Using Comparators
  5364.                                  -----------------
  5365.  
  5366.     Several POM command decide what to do by comparing two values. For example:
  5367.  
  5368.     IF $FLINE[1 3] = "XYZ" THEN x = "3" ELSE "4"
  5369.  
  5370.     In this example, if the first three characters of $FLINE are "XYZ", the
  5371.     variable x is set to "3", otherwise it is set to "4".  The first equals
  5372.     sign ("=") is a "comparator", because it defines how two values will be
  5373.     compared.  The second equals sign is not a comparator; it is simply
  5374.     padding, which makes the line easier to understand (see the section
  5375.     "Padding for Clarity" for details).
  5376.  
  5377.     Parse-O-Matic supports the following comparators:
  5378.  
  5379.            COMPARATOR   INTERPRETATION   MEANING                COMMENTS
  5380.            ----------   --------------   --------------------   --------
  5381.            =                Literal      Identical
  5382.            <>               Literal      Not identical
  5383.            >                Literal      Higher                 See NOTE
  5384.            >=               Literal      Higher, or identical   See NOTE
  5385.            <                Literal      Lower                  See NOTE
  5386.            <=               Literal      Lower, or identical    See NOTE
  5387.            ^                Literal      Contains
  5388.            ~                Literal      Does not contain
  5389.            LONGER           Literal      Length is longer
  5390.            SHORTER          Literal      Length is shorter
  5391.            SAMELEN          Literal      Length is the same
  5392.            #=              Numerical     Equal
  5393.            #<>             Numerical     Not equal
  5394.            #>              Numerical     Greater
  5395.            #>=             Numerical     Greater, or equal
  5396.            #<              Numerical     Less than
  5397.            #<=             Numerical     Less than, or equal
  5398.  
  5399.     NOTE:  Depends on PC-ASCII sort order.  Refer to the section "Literal
  5400.            Comparisons and Sort Order" for details.
  5401.  
  5402.     Whenever a comparator is required, but is omitted, it is assumed to be
  5403.     "literally identical".  Thus, the following lines are equivalent:
  5404.  
  5405.         IF x y z "3" "4"                   (This is very terse, but it works)
  5406.         IF x   y THEN z = "3" ELSE "4"     (The "equals" comparator is omitted)
  5407.         IF x = y THEN z = "3" ELSE "4"     (This is a lot easier to read)
  5408.  
  5409.     With some restrictions (discussed later), literal comparators work on
  5410.     numeric and alphabetic data.  Here are some examples of literal comparisons
  5411.     that are "true":
  5412.  
  5413.                    "ABC" <>      "ABCD"      "3" <>      "4"
  5414.                    "ABC" <=      "ABCD"      "3" <=      "4"
  5415.                    "ABC" <       "ABCD"      "3" <       "4"
  5416.                    "ABC" SHORTER "ABCD"      "3" SAMELEN "4"
  5417.  
  5418.                    "ABC" >=      "ABC"       "ABC" <>      "CDE"
  5419.                    "ABC" <=      "ABC"       "ABC" <=      "CDE"
  5420.                    "ABC" =       "ABC"       "ABC" <       "CDE"
  5421.                    "ABC" ^       "ABC"       "ABC" SAMELEN "CDE"
  5422.                    "ABC" SAMELEN "ABC"       "ABC" ~       "CDE"
  5423.  
  5424.  
  5425.     Literal Comparisons and Sort Order
  5426.     ----------------------------------
  5427.  
  5428.     Some of the literal comparators compare text according to "PC-ASCII sort
  5429.     order".  For plain English text, this works fine.  However, if your text
  5430.     contains diacritical (accented) characters, you should be aware that
  5431.     some comparisons will not work correctly.  For example, the "A-Umlaut"
  5432.     character appears in the PC-ASCII character set AFTER the PC-ASCII value
  5433.     for "Z".
  5434.  
  5435.  
  5436.     Numeric Comparisons
  5437.     -------------------
  5438.  
  5439.     Some confusion can arise if you use literal comparators on numbers.  For
  5440.     example, this doesn't work as you might expect at first glance:
  5441.  
  5442.     SET count = count+
  5443.     BEGIN count >= "2"
  5444.       OUTEND x = x |{count}
  5445.     END
  5446.  
  5447.     You might expect this POM file to output any number greater than or equal
  5448.     to "2", but in fact, you will get a different result, because the
  5449.     comparison is a literal (text) comparison.  In the example above, "2" to
  5450.     "9" are greater or equal to "2", but "10" (which starts with "1") is less,
  5451.     as is evident when you sort several numbers alphabetically:
  5452.  
  5453.     1
  5454.     10
  5455.     11
  5456.     15
  5457.     100
  5458.     2
  5459.     20
  5460.     200
  5461.     3
  5462.     30
  5463.  
  5464.     As you can see, the values 1, 10, 11 and 15 come before "2" when sorted
  5465.     alphabetically.
  5466.  
  5467.     To compare numbers, you should use the numeric comparators.  The correct
  5468.     way to code the previous example is as follows:
  5469.  
  5470.     SET count = count+
  5471.     BEGIN Count #>= "2"           <-- Note the #>= comparator
  5472.       OUTEND x = x |{count}
  5473.     END
  5474.  
  5475.     Written in this way, numbers greater than or equal to two will be output.
  5476.  
  5477.     Here are some examples of numeric comparisons that are "true":
  5478.  
  5479.                     "345" #<>  "567"         "1.23" #<>  "9.87"
  5480.  
  5481.                     "345" #<=  "567"         "1.23" #<=  "9.87"
  5482.  
  5483.                     "567" #>   "345"         "9.87" #>   "1.23"
  5484.  
  5485.                     "3"   #<   "6.2"
  5486.  
  5487.     The last example compares an integer ("3") with a real number ("6.2"). The
  5488.     numeric comparators automatically check if one of the numbers contains a
  5489.     decimal point.  In such case, the comparison is performed in "real number"
  5490.     mode, which imposes the accuracy restrictions described in the section "The
  5491.     CalcReal Command".  This might create a problem if you are comparing a
  5492.     decimal number with a large integer, but this is not a cause for much
  5493.     worry, since most parsing jobs tend to compare similar types of numbers.
  5494.  
  5495.  
  5496.     Upgrading from Earlier Versions
  5497.     -------------------------------
  5498.  
  5499.     IF YOU USED PARSE-O-MATIC PRIOR TO VERSION 3.00:  Because the comparator
  5500.     defaults to "literally identical" if it is omitted, POM files created
  5501.     before version 3.00 will continue to function normally -- with two notable
  5502.     exceptions. In older versions, the IGNORE and ACCEPT commands defaulted to
  5503.     "contains". If you have POM files that were created for older versions, you
  5504.     should check your IGNORE and ACCEPT commands to ensure that they are doing
  5505.     what you want them to.
  5506.  
  5507.  
  5508.                                ---------------------
  5509.                                Predefined Data Types
  5510.                                ---------------------
  5511.  
  5512.     For certain commands (e.g. MAKEDATA, MAKETEXT, GET and GETTEXT),
  5513.     Parse-O-Matic has internal definitions of certain data representations;
  5514.     these are known as Parse-O-Matic's "predefined data types":
  5515.  
  5516.            DATA TYPE  BYTES  MINIMUM VALUE MAXIMUM VALUE  COMMENTS
  5517.            ---------  -----  ------------- -------------  -----------
  5518.            BYTE         1                0           255
  5519.            INTEGER      2           -32768         32767
  5520.            LONGINT      4      -2147483648    2147483647
  5521.            REAL         6    -9999999999.9  9999999999.9  See NOTE #1
  5522.            SHORTINT     1             -128           127
  5523.            WORD         2                0         65535
  5524.            DATE         -                -             -  See NOTE #2
  5525.            TRIMMED      -          0 chars     255 chars  See NOTE #3
  5526.  
  5527.     NOTE #1:  The minimum and maximum values depend on the number of digits of
  5528.               precision.  See "The CalcReal Command" for details.
  5529.  
  5530.     NOTE #2:  The DATE type does not have a specific length.  In some input
  5531.               files, a date serial number might be represented by a numeric
  5532.               format such as INTEGER or LONGINT.  For more information, see
  5533.               the discussions of the MAKETEXT, MAKEDATA and GETTEXT commands.
  5534.  
  5535.     NOTE #3:  The TRIMMED type does not have a specific length.  You can use
  5536.               it with MAKETEXT and GETTEXT commands to remove the spaces, tabs
  5537.               and nulls on either side of a string.  It can also be used with
  5538.               MAKEDATA, but since this can produce a field of indeterminate
  5539.               length, it is rarely useful in such a role.
  5540.  
  5541.     Certain predefined data types can have a qualifier, which provides
  5542.     additional information.  All commands that use predefined data types will
  5543.     accept the qualifier, but only the MAKETEXT command makes use of it.
  5544.  
  5545.     DATA TYPE  QUALIFIER DESCRIPTION     EXAMPLES
  5546.     ---------  ------------------------  -------------------------------------
  5547.     REAL       Number of decimal places  "REAL 2" -> 3.14  "REAL 4" -> 3.1415
  5548.     DATE       Date format               "DATE ?y/?n/?d" -> "96/12/01"
  5549.  
  5550.  
  5551.     Interpreting Data Formats in a File
  5552.     -----------------------------------
  5553.  
  5554.     When inspecting a hex dump of a binary file, bear in mind that on
  5555.     PC-compatible computers, the bytes that comprise a number are often
  5556.     reversed.  For example, for the INTEGER and WORD data types, the eight most
  5557.     significant bits of numeric values are usually placed AFTER the eight least
  5558.     significant bits.  Thus, the decimal value 5099 will appear as EB 13 in the
  5559.     file, not 13 EB, despite the fact that decimal 5099 equals hex 13EB.
  5560.  
  5561.     If you are dealing with data that treats numbers differently, you can
  5562.     sometimes work around the problem by reversing the order of the bytes
  5563.     before performing the conversion.  For example, if the file contains a WORD
  5564.     data type, but has the most significant byte FIRST, you can switch things
  5565.     around, as demonstrated by this POM file:
  5566.  
  5567.     CHOP     0                      <-- Read the file manually
  5568.     GET      x "WORD"               <-- Get two bytes from the file
  5569.     APPEND   y = x[2] x[1]          <-- Flip the bytes around
  5570.     MAKETEXT z y "WORD"             <-- Convert the number
  5571.     OUTEND   |{z}                   <-- Output the result
  5572.  
  5573.  
  5574.  
  5575.     ===========================================================================
  5576.                                      TECHNIQUES
  5577.     ===========================================================================
  5578.  
  5579.  
  5580.                        --------------------------------------
  5581.                        Uninitialized and Persistent Variables
  5582.                        --------------------------------------
  5583.  
  5584.     Even before a variable is assigned a value (using the SET command, for
  5585.     example), you can use it in a POM command.  An uninitialized variable has a
  5586.     null value ("") and is treated normally by all commands.
  5587.  
  5588.     EXCEPTION:  To help you catch coding errors, the OUT and OUTEND commands
  5589.     do not allow you to output an uninitialized variable.  If you attempt to
  5590.     do so, Parse-O-Matic issues a warning, and processing is terminated.
  5591.  
  5592.     Variables are "persistent":  once you have assigned a value to a variable,
  5593.     it retains that value until it is changed.  Even if you open a new input
  5594.     file (see "POM and Wildcards") or a new output file (see "The OFile
  5595.     Command"), all variables will retain their values; they will not be "reset"
  5596.     back to null.  (Of course, when Parse-O-Matic ends, all variables
  5597.     disappear; they are not retained between separate runs of POM.)
  5598.  
  5599.  
  5600.     Example
  5601.     -------
  5602.  
  5603.     Here is an example which illustrates why persistent variables are useful:
  5604.  
  5605.     PAGELEN "55"                       <-- Set page length
  5606.     SET partnum = $FLINE[ 1 10]        <-- Extract the part number
  5607.     SET descrip = $FLINE[12 60]        <-- Extract the description
  5608.     BEGIN lastpart <> partnum          <-- Is this a new part number?
  5609.       OUTPAGE                          <-- Generate a page eject
  5610.       OUTHDG |PartNumber Description   <-- Output a heading
  5611.       OUTHDG |---------- -----------   <-- Output a heading
  5612.       SET    lastpart = partnum        <-- Remember the current part number
  5613.     END                                <-- End of BEGIN block
  5614.     OUTEND |{partnum} {descrip}        <-- Output the part number
  5615.  
  5616.     The first time a line is read from the input file, the lastpart variable
  5617.     will be null ("") because it has not yet been initialized.  As a result,
  5618.     the BEGIN block will be executed.  (The OUTPAGE command will be ignored
  5619.     in this first instance, since no data has been sent to the output file.)
  5620.     The BEGIN block also sets the lastpart variable, which will retain that
  5621.     value until it is changed.
  5622.  
  5623.     When the second input line is read (and the POM code is run again from the
  5624.     top), the BEGIN block will be run only if the current part number is
  5625.     different from the previous one (which we saved in the lastpart variable).
  5626.     However, if the partnum variable is different, the BEGIN block will be run,
  5627.     outputting the page eject and headings, and once again saving the partnum
  5628.     in the lastpart variable, so we can check it during the third input line --
  5629.     and so on.
  5630.  
  5631.                         ------------------------------------
  5632.                         Inline Incrementing and Decrementing
  5633.                         ------------------------------------
  5634.  
  5635.     You can add "1" to a variable in a command.  For example:
  5636.  
  5637.     SET x = "3"
  5638.     SET x = x+
  5639.  
  5640.     After the second statement, x would have the value "4".  Here are some
  5641.     additional examples:
  5642.  
  5643.     - Incrementing "1" gives you "2"
  5644.     - Incrementing "9" gives you "10"
  5645.     - Incrementing "99" gives you "100"
  5646.  
  5647.     The first time a variable is referenced, it has a null value (unless you
  5648.     SET it yourself).  If you increment a null variable, it will be changed
  5649.     from "" (i.e. null) to "1".
  5650.  
  5651.     You can also subtract "1" from a variable in a command:
  5652.  
  5653.     SET x = "3"
  5654.     SET x = x-
  5655.  
  5656.     After the second statement, x would have the value "2".  Here are some
  5657.     additional examples:
  5658.  
  5659.     - Decrementing "0" gives you "-1"
  5660.     - Decrementing "1" gives you "0"
  5661.     - Decrementing "99" gives you "98"
  5662.  
  5663.     When you do an inline increment or decrement, the variable itself is not
  5664.     changed.  (C programmers take note!)  For example:
  5665.  
  5666.     SET y = "3"
  5667.     SET x = y-
  5668.  
  5669.     After the second line, the x variable will equal "2", while the y variable
  5670.     will still equal "3".
  5671.  
  5672.     You can use inline incrementing or decrementing in conjunction with
  5673.     substrings:
  5674.  
  5675.     SET y = "X23X"
  5676.     SET x = y[2 3]+
  5677.  
  5678.     After the second line, the x variable will equal "24", while the y variable
  5679.     will still equal "X23X".
  5680.  
  5681.     Only integer numeric values can be incremented or decremented.  If you
  5682.     attempt to increment or decrement another type of variable (e.g. text or a
  5683.     decimal number), Parse-O-Matic will halt, and report an error.
  5684.  
  5685.  
  5686.                                    -------------
  5687.                                    Line Counters
  5688.                                    -------------
  5689.  
  5690.     If your input record is divided over several lines (due to its original
  5691.     format or perhaps because you used the SPLIT or CHOP command), it is
  5692.     helpful to set up a line counter.  The following example extracts the first
  5693.     six characters of the second line of input records that span three lines
  5694.     (designated lines 0, 1 & 2):
  5695.  
  5696.     IF     LineCntr = "1" THEN MyField = $FLINE[1 6]
  5697.     OUTEND LineCntr = "1" |{MyField}
  5698.     IF     LineCntr = "2" THEN LineCntr = "" ELSE LineCntr+
  5699.  
  5700.     For an alternative to line counters, see "The ReadNext Command".
  5701.  
  5702.  
  5703.                                       -------
  5704.                                       Tracing
  5705.                                       -------
  5706.  
  5707.     By setting the DOS variable POM to ALL, you can generate a trace file,
  5708.     named POM.TRC.  This is helpful if you have trouble understanding why your
  5709.     file isn't being parsed properly.  But be sure to test it with a SMALL
  5710.     input file; the trace is quite detailed, and it can easily generate a huge
  5711.     output file.
  5712.  
  5713.     To save space, you can specify a particular list of variables to be traced,
  5714.     rather than tracing everything.  For example, to trace only the variable
  5715.     PRICE, enter this DOS command:
  5716.  
  5717.     SET POM=PRICE
  5718.  
  5719.     To trace several variables, separate the variable names by slashes, as in
  5720.     this example:
  5721.  
  5722.     SET POM=PRICE/BONUS/NAME
  5723.  
  5724.     This traces the three variables PRICE, BONUS and NAME.
  5725.  
  5726.  
  5727.                                       -------
  5728.                                       Logging
  5729.                                       -------
  5730.  
  5731.     Every time Parse-O-Matic runs, it creates a "processing log".  This is a
  5732.     text file named POMLOG.TXT, which is placed in Parse-O-Matic's home
  5733.     directory.  (For example, if POM.EXE is located in C:\POM, the file will
  5734.     be C:\POM\POMLOG.TXT even if you run POM from another directory.)  If the
  5735.     file POMLOG.TXT already exists, it is renamed to POMLOG.BAK.
  5736.  
  5737.     The processing log file POMLOG.TXT contains a report of what happened
  5738.     during the last run of Parse-O-Matic.  Usually, the file will be quite
  5739.     short and look something like this:
  5740.  
  5741.         COMMAND: POM TEST.POM TEST.TXT TEMP.TXT
  5742.         DATE:    JAN 01 1996
  5743.  
  5744.         17:50:10 TEST.TXT opened for processing
  5745.         17:50:14 TEST.TXT processing completed
  5746.  
  5747.     The first line gives the DOS command line, while the second gives the
  5748.     date.  Subsequent lines give the time (Hours:Minutes:Seconds) and a
  5749.     progress or error message.
  5750.  
  5751.     If you encounter an error during processing, the text of the warning
  5752.     message is saved in the processing log.  It might look something like this:
  5753.  
  5754.         COMMAND: POM TEST.POM TEST.TXT TEMP.TXT
  5755.         DATE:    JAN 01 1996
  5756.  
  5757.         17:50:10 TEST.TXT opened for processing
  5758.         17:50:10 Execution error in line number 3 of POM file TEST.POM
  5759.         17:50:11 Required parameter is missing in OUT
  5760.  
  5761.     If you process multiple input files, POMLOG.TXT might look something
  5762.     like this:
  5763.  
  5764.         COMMAND: POM EXAMPL15.POM DATA*.TXT TEMP.TXT
  5765.         DATE:    JAN 01 1996
  5766.  
  5767.         14:21:27 DATA01.TXT opened for processing
  5768.         14:21:28 DATA01.TXT processing completed
  5769.  
  5770.         14:21:28 DATA02.TXT opened for processing
  5771.         14:21:28 DATA02.TXT processing completed
  5772.  
  5773.         14:21:28 DATA03.TXT opened for processing
  5774.         14:21:28 DATA03.TXT processing completed
  5775.  
  5776.     If for some reason the processing log can not be created, Parse-O-Matic
  5777.     will continue to run; it will not terminate.  For some additional comments
  5778.     on logging, see "Unattended Operation".
  5779.  
  5780.  
  5781.                                      ----------
  5782.                                      Quiet Mode
  5783.                                      ----------
  5784.  
  5785.     Sometimes you don't want the user to see the Parse-O-Matic processing
  5786.     screen.  In such cases, you can use the "Quiet Mode" switch (/Q) on the
  5787.     command line.  For example:
  5788.  
  5789.     POM XYZ.POM MYFILE.TXT TEMP.TXT /Q
  5790.  
  5791.     The /Q switch suppresses the display of the processing screen.  The only
  5792.     time a user will see anything is if there is a problem (for example:  the
  5793.     input file was not found).  In such case, Parse-O-Matic will make a noise
  5794.     via the PC speaker, then display a message (see "Unattended Operation" and
  5795.     "The MSGWAIT Command" for some background information).
  5796.  
  5797.  
  5798.                                 -------------------
  5799.                                 The ShowNum Utility
  5800.                                 -------------------
  5801.  
  5802.     The ShowNum program (SHOWNUM.EXE in the standard Parse-O-Matic package) is
  5803.     a small utility which converts a hex number to decimal and vice-versa.
  5804.     This is helpful if you are using a hexadecimal file dump to locate specific
  5805.     numeric data in a binary file.
  5806.  
  5807.     To find out what the decimal number 123 is in hexadecimal, enter the
  5808.     following command at the DOS prompt:
  5809.  
  5810.     SHOWNUM 123
  5811.  
  5812.     This will display:
  5813.  
  5814.     123 = $7B
  5815.  
  5816.     To find out what hex 400F is in decimal, enter the following command at
  5817.     the DOS prompt:
  5818.  
  5819.     SHOWNUM $400F
  5820.  
  5821.     The $ character tells ShowNum that the number is in hexadecimal.  The
  5822.     program will display:
  5823.  
  5824.     $400F = 16399
  5825.  
  5826.     ShowNum can handle numbers between -2,147,483,648 (hex $80000000) and
  5827.     2,147,483,647 (hex $7FFFFFFF).
  5828.  
  5829.  
  5830.  
  5831.     ===========================================================================
  5832.                                    FILE HANDLING
  5833.     ===========================================================================
  5834.  
  5835.  
  5836.                        -------------------------------------
  5837.                        How Parse-O-Matic Searches for a File
  5838.                        -------------------------------------
  5839.  
  5840.     When Parse-O-Matic needs to read a file, it follows this procedure:
  5841.  
  5842.     1)  Parse-O-Matic tidies up the file name in the following ways:
  5843.  
  5844.         - It removes spaces and tabs
  5845.         - It converts the file name to uppercase
  5846.         - As per DOS convention, slashes (/) are converted to backslashes (\)
  5847.         - If this type of file has a default extension, and if the file name
  5848.           does not have a period (i.e. dot) in the name, the extension is
  5849.           added.
  5850.  
  5851.     2)  If the file name is fully qualified (i.e. drive and path, or both),
  5852.         Parse-O-Matic tries to open that file.  If it can not, it terminates
  5853.         with an error message.
  5854.  
  5855.     3)  If the file name is not fully qualified, Parse-O-Matic follows this
  5856.         procedure:
  5857.  
  5858.         - It first looks for the file in the current directory.
  5859.         - If then looks in the directory where the Parse-O-Matic program
  5860.           (POM.EXE) is located.
  5861.         - It then searches the DOS PATH for the file.  (For information
  5862.           about the PATH command, refer to your DOS manual.)
  5863.         - If none of these steps locate the file, Parse-O-Matic terminates
  5864.           with an error message.
  5865.  
  5866.     The following types of files are affected...
  5867.  
  5868.     TYPE OF FILE            DEFAULT EXTENSION  REFER TO MANUAL SECTION
  5869.     ----------------------  -----------------  -----------------------
  5870.     POM (Control) File            .POM         "The POM File"
  5871.     Date Information File      See NOTE #1     "The POMDATE.CFG File"
  5872.     Lookup File                See NOTE #2     "The LookFile Command"
  5873.     Properization Exception    See NOTE #2     "The Proper Command"
  5874.     Map File                      .MPF         "The MAPFILE Command"
  5875.  
  5876.     NOTE #1:  The Date Information File is always called POMDATE.CFG.  You can
  5877.               put your standard version in the Parse-O-Matic directory. If you
  5878.               wish to override it, you should place the modified copy in your
  5879.               current (logged) directory.
  5880.  
  5881.     NOTE #2:  This type of file does not have a default extension.  However, we
  5882.               recommend "TBL" (i.e. "Table") for Lookup files and "PEF" for
  5883.               Properization Exception Files.
  5884.  
  5885.     Parse-O-Matic does NOT search for input and output files.  They must be
  5886.     in the current directory, or must have a fully qualfied path.  If the
  5887.     input file is missing an extension, it is assumed to be TXT.  If the
  5888.     output file is not specified in the POM command, it is assumed to be
  5889.     POMOUT.TXT, in the current directory.  (See "How Parse-O-Matic Opens an
  5890.     Output File")
  5891.  
  5892.     Since Parse-O-Matic searches for files, you can place frequently-used
  5893.     Lookup and POM files in a directory in your DOS path.
  5894.  
  5895.  
  5896.                        --------------------------------------
  5897.                        How Parse-O-Matic Opens an Output File
  5898.                        --------------------------------------
  5899.  
  5900.     Parse-O-Matic opens an output file the first time one of the output
  5901.     commands (e.g. OUT, OUTEND, OUTHDG) has something to send to the file.
  5902.     When opening an output file, Parse-O-Matic follows this procedure:
  5903.  
  5904.     1)  Normally, the name of the output file is specified on the POM command
  5905.         line or (if it is omitted there), it is specified in an OFILE command
  5906.         within the POM file.
  5907.  
  5908.         If no output file name was given using either method, the name is set
  5909.         to POMOUT.TXT (in the current directory).
  5910.  
  5911.     2)  Parse-O-Matic tidies up the file name in the following ways:
  5912.  
  5913.         - It removes spaces and tabs
  5914.         - It converts the file name to uppercase
  5915.         - As per DOS convention, slashes (/) are converted to backslashes (\)
  5916.         - If the file name does not have an extension, and it does not end in
  5917.           a period or a colon, the extension TXT is added.  Thus:
  5918.  
  5919.           C:\XYZ      becomes C:\XYZ.TXT
  5920.           C:\XYZ.     stays the same
  5921.           C:\XYZ.DAT  stays the same
  5922.           LPT2:       stays the same (see "Sending Output to a Device")
  5923.  
  5924.     3)  The output file name is compared to the input file name.  If they are
  5925.         the same, Parse-O-Matic terminates with an error.  You can not send
  5926.         output to the input file, nor can you read input from the output file.
  5927.  
  5928.     4A) If the file name is preceded by a plus sign ("+"), Parse-O-Matic will
  5929.         append output to the file.  Here are some examples:
  5930.  
  5931.         +C:\XYZ.TXT   output will be appended to the file
  5932.         +LPT1:        this refers to a device, so the "+" is ignored
  5933.  
  5934.         If the file to which you are appending does not already exist, it is
  5935.         first created, as an empty file.
  5936.  
  5937.     4B) If the file name is NOT preceded by a plus sign, the following
  5938.         procedure takes place:
  5939.  
  5940.         - If a file with the specified name already exists, it is renamed
  5941.           with a .BAK extension (replacing any previous file with that name).
  5942.         - The file is created, as an empty file
  5943.  
  5944.         For example, if you run Parse-O-Matic as follows:
  5945.  
  5946.         POM MYPOM.POM INPUT.TXT C:\XYZ.TXT
  5947.  
  5948.         then if C:\XYZ.TXT already exists, it is renamed to C:\XYZ.BAK.
  5949.  
  5950.     5)  Output is directed to the output file until Parse-O-Matic ends or a new
  5951.         output file name is specified by the OFILE command.
  5952.  
  5953.     REMINDER:  Parse-O-Matic does not open the output file until it is time to
  5954.     send it some data from the output commands (OUT, OUTEND etc.).  If no data
  5955.     is sent to the output file, it will contain its original data (assuming it
  5956.     already existed).  If this is a problem, you can either delete the output
  5957.     file before running Parse-O-Matic, or place the following commands in the
  5958.     PROLOGUE:
  5959.  
  5960.     ERASE "OUTPUT.TXT"      <-- Delete the output file
  5961.     OFILE "OUTPUT.TXT"      <-- Specify the output file
  5962.  
  5963.     If you do this, and no data is sent to the output file, the file will not
  5964.     exist.  You can check if POM failed by consulting the DOS ERRORLEVEL.
  5965.     (See your DOS manual for an explanation of ERRORLEVEL.)
  5966.  
  5967.     - If the ERRORLEVEL is 0 and the file does not exist, it means that POM
  5968.       ran successfully, but no output was sent to the file.
  5969.  
  5970.     - If the ERRORLEVEL is 1 or higher, and the file does not exist, it
  5971.       means that POM failed, or you used the HALT command before any output
  5972.       was sent to the file.
  5973.  
  5974.     If you are calling Parse-O-Matic from a program (rather than a batch file),
  5975.     you can check the error level using the facilities built in to the language
  5976.     in which the program was written.  For example, Turbo Pascal lets you
  5977.     run another program with the EXEC command, after which you can extract the
  5978.     ERRORLEVEL from the low byte of the DosExitCode variable.
  5979.  
  5980.  
  5981.                             ---------------------------
  5982.                             Appending to an Output File
  5983.                             ---------------------------
  5984.  
  5985.     If you want to add data to the end of the output file, you have three
  5986.     alternatives:
  5987.  
  5988.     1)  Use wildcards, as explained in "POM and Wildcards".  In such case,
  5989.         the output file is empty when the first output line is generated
  5990.         (although see method #2 for an exception).  When processing with
  5991.         wildcards, all output is sent to the same file, unless you change
  5992.         the file with the OFILE command (see "The OFile Command").
  5993.  
  5994.     2)  Prefix the output file name with a plus sign.  This tells Parse-O-
  5995.         Matic that you want to add data to the end of the file, rather than
  5996.         starting with an empty file.  You can use this method on the command
  5997.         line:
  5998.  
  5999.         POM MYPOM.POM INPUT.TXT +C:\MYFILES\OUTPUT.TXT
  6000.  
  6001.         You can also use this method in the OFILE command:
  6002.  
  6003.         OFILE "+C:\MYFILES\OUTPUT.TXT"
  6004.  
  6005.         In these examples, we provided the full path name to the output file.
  6006.         If you do not specify a path name (e.g. OFILE "+OUTPUT.TXT"), the
  6007.         output file is placed in the current directory.
  6008.  
  6009.     3)  Use a batch file and the DOS COPY command to control the concatenation
  6010.         of output files.  This method is less convenient, but it allows you to
  6011.         bypass the addition of the new output if there is a processing error.
  6012.         Here is a sample batch file (comments appear after the arrows):
  6013.  
  6014.         @ECHO OFF                               <-- Turn batch echoing off
  6015.         IF EXIST OUTPUT.TXT DELETE OUTPUT.TXT   <-- Get rid of old output file
  6016.         POM MYPOM.POM INPUT.TXT OUTPUT.TXT      <-- Parse the input file
  6017.         IF ERRORLEVEL 1 GOTO QUIT               <-- Quit if there was an error
  6018.         IF NOT EXIST OUTPUT.TXT GOTO QUIT       <-- Quit if no output generated
  6019.         IF EXIST SAFETY.TXT DELETE SAFETY.TXT   <-- Get rid of old safety file
  6020.         RENAME MAINFILE.TXT SAFETY.TXT          <-- Backup the original file
  6021.         COPY SAVE.TXT+OUTPUT.TXT MAINFILE.TXT   <-- Add the new output
  6022.         :QUIT                                   <-- Batch file label for GOTO
  6023.  
  6024.         This method has the added advantage of creating a backup copy of the
  6025.         original output file.  If the data in the file is particularly
  6026.         important, you could place the file SAFETY.TXT on another hard drive.
  6027.  
  6028.  
  6029.                              --------------------------
  6030.                              Sending Output to a Device
  6031.                              --------------------------
  6032.  
  6033.     Parse-O-Matic recognizes that an "output file" is actually a device if it
  6034.     has a colon (":") at the end of the name.  You can direct Parse-O-Matic's
  6035.     output to a standard device such as COM1: or LPT2: by specifying the device
  6036.     name accordingly. For example:
  6037.  
  6038.     POM XYZ.POM INPUT.TXT LPT1:
  6039.  
  6040.     This directs the output to the LPT1 printer.
  6041.  
  6042.     Parse-O-Matic can detect a "Not Ready" condition in most cases.  A printer
  6043.     is Not Ready when it is offline, out of paper, or its print buffer is full.
  6044.  
  6045.     If a Not Ready condition occurs, the following happens:
  6046.  
  6047.     - If you are running in Quiet Mode (/Q on the POM command line), a Not
  6048.       Ready condition terminates Parse-O-Matic with a DOS ERRORLEVEL of 243.
  6049.  
  6050.     - If you are not running in Quiet Mode, a message box gives you the option
  6051.       of trying again, or cancelling processing.  If you cancel, Parse-O-Matic
  6052.       terminates with a DOS ERRORLEVEL of 244.
  6053.  
  6054.  
  6055.     COM Ports
  6056.     ---------
  6057.  
  6058.     If you are sending output to a COM port (e.g. COM1:) you should first set
  6059.     the baud rate with the DOS MODE command, or Pinnacle Software's MODEM
  6060.     program (available on our BBS and Web site).
  6061.  
  6062.     The MODEM program is particularly useful if your COM port is driving a
  6063.     modem.  Parse-O-Matic talks to the operating system's COM device driver
  6064.     rather than the modem itself, so before you send data to a modem, it is a
  6065.     good idea to use the MODEM program to check that the modem is online and
  6066.     functioning properly.
  6067.  
  6068.     If you are using a high-speed modem (9600 bps or higher) and you find that
  6069.     you sometimes lose some characters, the operating system or the modem may
  6070.     not be handling a "Not Ready" condition properly during handshaking.  In
  6071.     such case, you may find it necessary to turn off buffering (locked DTE
  6072.     speed) and run at a maximum speed of 9600 bps.  For a quick course in
  6073.     high-speed modems and buffering, see the Trouble-Shooting Guide included
  6074.     with Pinnacle Software's Sapphire Bulletin Board System (also available on
  6075.     our BBS and Web site).
  6076.  
  6077.     For an example of sending output to a COM port, see "The Pause Command".
  6078.  
  6079.  
  6080.                                      ---------
  6081.                                      DbF Files
  6082.                                      ---------
  6083.  
  6084.     If Parse-O-Matic notices that the input file is a "DBase" file (i.e. it has
  6085.     a DBF extension -- for example:  MYFILE.DBF), it will change the way it
  6086.     processes the data.  For instance, the variable $FLINE is not defined.
  6087.     Rather, each of the fields in the database are pre-parsed.  Thus, if you
  6088.     have a DBF file containing three fields (EMPNUM, NAME, PHONE), your entire
  6089.     POM file might look like this:
  6090.  
  6091.     IGNORE DELETED "Y"
  6092.     OUTEND |{EMPNUM} {NAME} {PHONE}
  6093.  
  6094.     The DELETED variable is created automatically for each record.  If it is
  6095.     set to "Y", it means the record has been deleted from the database and is
  6096.     probably not valid.  In most cases, you will want to ignore such records.
  6097.  
  6098.     If you do not know what the field names are, you can obtain the list with
  6099.     the following POM file:
  6100.  
  6101.     TRACE DELETED
  6102.  
  6103.     Afterwards, when you inspect the trace file (POM.TRC), you will see a
  6104.     summary of all the fields.  Since there are no output commands (e.g. OUTEND
  6105.     and OUTHDG), the output file will be empty.
  6106.  
  6107.     NOTE:  Parse-O-Matic does not currently support DBF "Memo" fields.
  6108.  
  6109.  
  6110.                                  -----------------
  6111.                                  POM and Wildcards
  6112.                                  -----------------
  6113.  
  6114.     You can process multiple input files with the same POM file by specifying a
  6115.     DOS "wildcard" at the DOS command prompt.  All output is then directed to
  6116.     the same output file.  For example:
  6117.  
  6118.     POM XYZ.POM *.TXT OUTPUT.TXT
  6119.  
  6120.     This runs XYZ POM.file on each file in the current directory with a TXT
  6121.     extension and sends all output to the file OUTPUT.TXT.
  6122.  
  6123.     The POM file can determine which file it is reading by using the predefined
  6124.     variable $COMMAND, which contains the current POM command line.
  6125.  
  6126.     Consider the following scenario:
  6127.  
  6128.     - You have installed POM.EXE in the directory path C:\UTILITY\POM
  6129.     - The current directory contains ABC.POM, MARK.TXT, MARY.TXT and JOHN.TXT
  6130.     - You enter the command POM ABC *.DAT OUT.TXT
  6131.  
  6132.     Parse-O-Matic runs ABC.POM against the three TXT files.  On the first input
  6133.     file, $COMMAND will look like this:
  6134.  
  6135.     C:\UTILITY\POM.EXE ABC.POM MARK.TXT OUT.TXT
  6136.  
  6137.     On the next two input files, it looks like this:
  6138.  
  6139.     C:\UTILITY\POM.EXE ABC.POM MARY.TXT OUT.TXT
  6140.     C:\UTILITY\POM.EXE ABC.POM JOHN.TXT OUT.TXT
  6141.  
  6142.     Note that the file OUT.TXT is NOT processed, even though it has a TXT
  6143.     extension.  POM will always avoid processing the output file.
  6144.  
  6145.     Let's say you wanted to concatenate both MARK.TXT and MARY.TXT, and put the
  6146.     file name at the top.  You could do it with this POM file, named ABC.POM:
  6147.  
  6148.     SET cmd = $COMMAND                <-- Get the command line
  6149.     BEGIN cmd <> lastcmd              <-- Has it changed?
  6150.       PARSE  fname cmd "2* " "3* "    <-- Extract the input file name
  6151.       SETLEN flen  fname              <-- Get length of input file name
  6152.       SET    uline = ""               <-- Initialize underline
  6153.       PAD    uline "L" "-" flen       <-- Set underline
  6154.       OUTEND lastcmd <> "" |          <-- Output a linefeed unless
  6155.       OUTEND lastcmd <> "" |          <-- this is the first file
  6156.       OUTEND |{fname}                 <-- Output the file name
  6157.       OUTEND |{uline}                 <-- Output the underline
  6158.       OUTEND |                        <-- Output a linefeed
  6159.       SET    lastcmd = $COMMAND       <-- Remember this command line
  6160.     END                               <-- End of code block
  6161.     OUTEND |{$FLINE}                  <-- Output a line from the input
  6162.  
  6163.     You could then process MARK.TXT and MARY.TXT with this command line:
  6164.  
  6165.     POM ABC M*.TXT OUT.TXT
  6166.  
  6167.     This processes any file starting with an "M" that has a TXT extension.
  6168.  
  6169.     Another way to run the command is as follows:
  6170.  
  6171.     POM ABC M???.TXT OUT.TXT
  6172.  
  6173.     This processes any four-letter TXT file that starts with "M".
  6174.  
  6175.     For more information about DOS wildcards, consult your DOS manual.
  6176.  
  6177.  
  6178.                               -----------------------
  6179.                               Solving Memory Problems
  6180.                               -----------------------
  6181.  
  6182.     Parse-O-Matic does all of its work in standard memory; it does not use
  6183.     Extended or Expanded memory.  This is rarely a problem, but if you do
  6184.     somehow run out of memory, there are some steps you can take...
  6185.  
  6186.     You can often free up some extra memory by unloading unused device drivers
  6187.     and DOS TSR ("Terminate and Stay Resident") programs.  (TSR's are sometimes
  6188.     called "DOS Pop-Ups")
  6189.  
  6190.     Alternatively, most drivers and TSR's can be safely moved into high memory,
  6191.     using the LOADHIGH function in your AUTOEXEC.BAT, or the DEVICEHIGH
  6192.     function in CONFIG.SYS.  Some older drivers and TSR's will not tolerate
  6193.     this kind of relocation.
  6194.  
  6195.  
  6196.  
  6197.     ===========================================================================
  6198.                                 OPERATIONAL PLANNING
  6199.     ===========================================================================
  6200.  
  6201.  
  6202.                             ----------------------------
  6203.                             Effective Use of Batch Files
  6204.                             ----------------------------
  6205.  
  6206.     The built-in batch (BAT) capability of DOS and Windows is often overlooked,
  6207.     even by seasoned computer professionals.  You can use batch files to make
  6208.     Parse-O-Matic easier to use.  Batch files are created with a text editor
  6209.     (such as DOS EDIT, or Windows Notepad).
  6210.  
  6211.  
  6212.     Example #1:  Save Yourself Some Typing
  6213.     --------------------------------------
  6214.  
  6215.     Here is a simple batch file (comments appear after the arrows):
  6216.  
  6217.     @ECHO OFF                               <-- Turn off command-line echoing
  6218.     POM MYPOM.POM INPUT.TXT OUTPUT.TXT      <-- Run Parse-O-Matic
  6219.     IF ERRORLEVEL 1 GOTO QUIT               <-- Quit if an error occured
  6220.     SEE OUTPUT.TXT                          <-- View the output file
  6221.     :QUIT                                   <-- Batch file label
  6222.  
  6223.     The advantage of this batch file is that it saves you the trouble of typing
  6224.     in the entire POM command line each time you want to parse the file.
  6225.  
  6226.  
  6227.     Example #2:  Streamline Your Development
  6228.     ----------------------------------------
  6229.  
  6230.     Here is a batch file which is useful during the development of a POM file.
  6231.  
  6232.     @ECHO OFF
  6233.     DEVELOP 50 MYPOM.POM IN.TXT C:\MYFILES\OUT.TXT
  6234.  
  6235.     This batch file calls DEVELOP.BAT (included with Parse-O-Matic), which
  6236.     displays a menu with the following options:
  6237.  
  6238.     INPUT ------ View input file
  6239.     EDIT ------- Edit POM file
  6240.     PARSE ------ Run parsing job
  6241.     OUTPUT ----- View output file
  6242.     QUIT ------- Finished
  6243.  
  6244.     This lets you try parsing, view the result, make changes to the POM file
  6245.     if necessary, then parse again.  You will find that this technique makes
  6246.     development proceed quickly.
  6247.  
  6248.     Here is an explanation of the second line of the batch file:
  6249.  
  6250.     DEVELOP 50 MYPOM.POM IN.TXT C:\MYFILES\OUT.TXT
  6251.     :       :  :         :      :
  6252.     :       :  :         :      :
  6253.     :       :  :         :      Name of output file  <-----
  6254.     :       :  :         :                                |
  6255.     :       :  :         Name of input file          <-------- See NOTE #1
  6256.     :       :  :                                          |
  6257.     :       :  Name of POM file                      <-----
  6258.     :       :
  6259.     :       Save position for menu                   <-------- See NOTE #2
  6260.     :
  6261.     Invokes the batch file DEVELOP.BAT
  6262.  
  6263.     NOTE #1:  You must provide the full path to the files (unless they are in
  6264.               the current directory) and the extension.
  6265.  
  6266.     NOTE #2:  The "save position" remembers where you were in the menu.  You
  6267.               may use values 49 to 99 to provide a "memory" for 50 different
  6268.               batch files that call DEVELOP.BAT.  (The other values are
  6269.               reserved for the Parse-O-Matic installation and tutorial
  6270.               procedures.)  If 50 is not enough, you can place additional
  6271.               batch files in another directory; the menu save file (POM.MSV)
  6272.               is always placed in the current directory.
  6273.  
  6274.     In order for DEVELOP.BAT to work correctly when you are in a directory
  6275.     other than the Parse-O-Matic directory, you must place the Parse-O-Matic
  6276.     directory in your DOS PATH (see your DOS manual for details).  Your PATH
  6277.     must also include the directory to a text editor.  (In the original
  6278.     Parse-O-Matic package, DEVELOP.BAT calls up DOS EDIT.)
  6279.  
  6280.     You may find it instructive to study the file DEVELOP.BAT by loading it
  6281.     into a text editor.  The batch file contains some comments which explain
  6282.     how it works.  As mentioned in one of the comments, you may wish to change
  6283.     the text editor that the batch file calls for editing the POM file.
  6284.  
  6285.     You may also find the program MENU.EXE useful.  For a brief description,
  6286.     type MENU /? at the DOS prompt.  To study a typical menu definition file,
  6287.     enter the command SEE POM.MNU at the DOS prompt.
  6288.  
  6289.  
  6290.     Example #3:  Automatic Batch Files
  6291.     ----------------------------------
  6292.  
  6293.     Let's say that each day you have a text file, named DELLIST.TXT, which
  6294.     lists the names of the files that need to be deleted:
  6295.  
  6296.     FRED.TXT
  6297.     MARY.TXT
  6298.     JOHN.TXT
  6299.     HARRY.TXT
  6300.  
  6301.     You could write a POM file (we'll call it MAKEDEL.POM) to write a batch
  6302.     file to delete the files.  It would look like this:
  6303.  
  6304.     PROLOGUE
  6305.       OUTEND |@ECHO OFF
  6306.     END
  6307.     IGNORE $FLINE = "COMMAND.COM"           <-- An example of a safety feature!
  6308.     OUTEND $FLINE <> "" |DEL {$FLINE}
  6309.  
  6310.     You could automate the entire procedure with the following batch file
  6311.     (which we'll call DAILYDEL.BAT):
  6312.  
  6313.     @ECHO OFF                               <-- Turn off command-line echoing
  6314.     POM MAKEDEL.POM DELLIST.TXT TEMP.BAT    <-- Create the batch file TEMP.BAT
  6315.     IF ERRORLEVEL 1 GOTO QUIT               <-- Quit if an error occured
  6316.     TEMP.BAT                                <-- Run the batch file
  6317.     DEL TEMP.BAT                            <-- Delete it
  6318.     :QUIT                                   <-- Batch file label
  6319.  
  6320.     The second line of DAILYDEL.BAT runs Parse-O-Matic to create a batch file
  6321.     named TEMP.BAT.  Given the input file shown earlier, TEMP.BAT would look
  6322.     like this:
  6323.  
  6324.     @ECHO OFF
  6325.     DEL FRED.TXT
  6326.     DEL MARY.TXT
  6327.     DEL JOHN.TXT
  6328.     DEL HARRY.TXT
  6329.  
  6330.     After TEMP.BAT is created, DAILYDEL.BAT runs TEMP.BAT (thus deleting all
  6331.     the files listed in DELLIST.TXT).
  6332.  
  6333.     This is only a simple example.  Parse-O-Matic's ability to create batch
  6334.     files based on input data provides you with a very powerful tool for
  6335.     automating daily administrative tasks.
  6336.  
  6337.     When you write automatic applications, you should be careful to include
  6338.     routines in both the batch files and the POM files to handle any unusual
  6339.     conditions.  In MAKEDEL.POM, we checked the file to be sure that it wasn't
  6340.     "COMMAND.COM", because if that file is deleted, your system will probably
  6341.     stop working!
  6342.  
  6343.  
  6344.     Example #4:  Controlling a POM File from the Command Line
  6345.     ---------------------------------------------------------
  6346.  
  6347.     Consider the following batch file, which we will call SELECT.BAT:
  6348.  
  6349.     @ECHO OFF                          <-- Turn off command-line echoing
  6350.     IF (%1) == () GOTO ERROR           <-- Make sure we have a parameter
  6351.     SET XYZ=%1                         <-- Set the environment variable XYZ
  6352.     POM SELECT.POM INPUT.TXT OUT.TXT   <-- Run the POM file SELECT.POM
  6353.     GOTO QUIT                          <-- Jump to the QUIT label
  6354.     :ERROR                             <-+
  6355.     ECHO Missing parameter               | Error-handling routine
  6356.     PAUSE                              <-+
  6357.     :QUIT                              <-- Batch file label
  6358.     SET XYZ=                           <-- Get rid of the environment variable
  6359.  
  6360.     SELECT.BAT can be used with this POM file, which will we name SELECT.POM:
  6361.  
  6362.     PROLOGUE
  6363.       GETENV xyz "XYZ"
  6364.     END
  6365.     OUTEND $FLINE ^ xyz |{$FLINE}
  6366.  
  6367.     You can use SELECT.BAT to output only those lines that contain the variable
  6368.     that you specify.  For example, you can enter the following command at the
  6369.     DOS prompt:
  6370.  
  6371.     SELECT MARY
  6372.  
  6373.     This will output only those lines (from INPUT.TXT) that contain "MARY".
  6374.     If you wish to ignore distinctions between uppercase and lowercase, change
  6375.     the last line of SELECT.POM accordingly:
  6376.  
  6377.     OUTEND $FLUPC ^ xyz |{$FLINE}
  6378.  
  6379.     Batch file parameters are separated by spaces on the command line, so the
  6380.     following command would not work as you might expect:
  6381.  
  6382.     SELECT MARY FRED JOHN
  6383.  
  6384.     This would set the batch variable %1 to MARY, %2 to FRED and %3 to JOHN.
  6385.  
  6386.     One way to deal with this is to eliminate the spaces when you run the
  6387.     batch file:
  6388.  
  6389.     SELECT MARY/FRED/JOHN
  6390.  
  6391.     You can then replace the OUTEND command in SELECT.POM with these lines:
  6392.  
  6393.     APPEND x xyz "/"               <-- Set the x variable to "MARY/FRED/JOHN/"
  6394.     BEGIN x <> ""                  <-- We will loop through all of the names
  6395.       PEEL y x "" "/"              <-- Move a name to the y variable
  6396.       OUTEND $FLUPC ^ y |{$FLINE}  <-- Output a line if it contains the name
  6397.     AGAIN                          <-- Go back to the BEGIN
  6398.  
  6399.     Bear in mind that the system environment space is limited.  If you have
  6400.     problems with an application like this one, refer to "The GETENV Command",
  6401.     in the section entitled "Disappearing Environment Variables".
  6402.  
  6403.  
  6404.                      ------------------------------------------
  6405.                      Running Parse-O-Matic from Another Program
  6406.                      ------------------------------------------
  6407.  
  6408.     If you are calling Parse-O-Matic from a program written in a high-level
  6409.     language (such as Pascal, Delphi, C or Basic), you can check its success or
  6410.     failure by consulting the "DOS Error Level".  Most languages have built-in
  6411.     facilities to test this value.
  6412.  
  6413.     For example, Turbo Pascal lets you run another program with the EXEC
  6414.     command, after which you can extract the ERRORLEVEL from the low byte of
  6415.     the DosExitCode variable.  You can also check the DOSERROR return code
  6416.     to check for invocation errors.  Some typical errors include:
  6417.  
  6418.     Program not found, Path not found, Access denied, Not enough memory.
  6419.  
  6420.     Windows developers should avoid running Parse-O-Matic in a minimized window
  6421.     because if an error occurs, the user will not see the message.  In such
  6422.     case, Parse-O-Matic can terminate after a suitable delay (see "The MSGWAIT
  6423.     Command"), but the mysterious pause might cause the user some concern.
  6424.  
  6425.     On long parsing jobs (taking 3 seconds or more on your slowest machine),
  6426.     it is perhaps best to let the user see the processing screen rather than
  6427.     running in Quiet Mode (see "Quiet Mode").  If nothing else, it gives him
  6428.     or her something to look at, and provides assurance that the machine has
  6429.     not locked up.
  6430.  
  6431.  
  6432.                                 --------------------
  6433.                                 Unattended Operation
  6434.                                 --------------------
  6435.  
  6436.     You can design applications that run themselves while you are not there.
  6437.     There are two reasons why you might want to do this:
  6438.  
  6439.     - You can run long processing jobs just before leaving work at night
  6440.     - Parse-O-Matic is useful, but it isn't very interesting to watch!
  6441.  
  6442.     Several features of Parse-O-Matic facilitate "unattended operation".
  6443.  
  6444.     - The SOUND command can alert you if something unusual happens; you don't
  6445.       have to stare at the screen to make sure that everything is working.
  6446.  
  6447.     - All error messages (which say "Press a key to continue") make a noise
  6448.       via the PC speaker (see "The Sound Command").
  6449.  
  6450.     - You can use the MSGWAIT command to let processing continue if there is
  6451.       an error (see "The MSGWAIT Command").
  6452.  
  6453.     - The processing log (see "Logging") can be used to check processing.
  6454.  
  6455.     Let's say you wanted to concatenate (add together) several enormous text
  6456.     files.  You could start with the following POM file (named ADD.POM):
  6457.  
  6458.     SET    cmd = $COMMAND
  6459.     BEGIN  cmd <> lastcmd
  6460.       SOUND  "BEEP"
  6461.       SET     lastcmd = cmd
  6462.     END
  6463.     OUTEND |{$FLINE}
  6464.  
  6465.     You could then enter the command POM ADD.POM *.TXT ALL.TXT and walk away.
  6466.     Whenever a new file is started, you'll hear a beep.  When you come back,
  6467.     you can check the file POMLOG.TXT (which will be located in the same
  6468.     directory as POM.EXE).  It might look something like this:
  6469.  
  6470.     COMMAND: POM ADD.POM *.TXT ALL.TXT
  6471.     DATE:    JAN 01 1996
  6472.  
  6473.     16:39:12 JOHN.TXT opened for processing
  6474.     16:45:28 JOHN.TXT processing completed
  6475.  
  6476.     16:45:29 MARY.TXT opened for processing
  6477.     16:52:10 MARY.TXT processing completed
  6478.  
  6479.     16:52:11 FRED.TXT opened for processing
  6480.     17:03:33 FRED.TXT processing completed
  6481.  
  6482.     If you are processing multiple files, and each one uses a different POM
  6483.     file (and hence requires a separate run of Parse-O-Matic) you can write
  6484.     your batch file so that it renames the log files.  This lets you review
  6485.     each log file later.  For example:
  6486.  
  6487.     @ECHO OFF
  6488.     POM JOHN.POM JOHN.TXT JOHN.LST
  6489.     RENAME C:\POM\POMLOG.TXT JOHN.LOG
  6490.     POM MARY.POM MARY.TXT MARY.LST
  6491.     RENAME C:\POM\POMLOG.TXT MARY.LOG
  6492.     POM FRED.POM FRED.TXT FRED.LST
  6493.     RENAME C:\POM\POMLOG.TXT FRED.LOG
  6494.  
  6495.     When processing is complete, the files JOHN.LOG, MARY.LOG and FRED.LOG
  6496.     will be available in the directory C:\POM for your inspection.
  6497.  
  6498.     Here is a slightly more sophisticated version of the batch file:
  6499.  
  6500.     @ECHO OFF
  6501.     POM JOHN.POM JOHN.TXT JOHN.LST
  6502.     IF ERRORLEVEL 1 GOTO QUIT
  6503.     RENAME C:\POM\POMLOG.TXT JOHN.LOG
  6504.     POM MARY.POM MARY.TXT MARY.LST
  6505.     IF ERRORLEVEL 1 GOTO QUIT
  6506.     RENAME C:\POM\POMLOG.TXT MARY.LOG
  6507.     POM FRED.POM FRED.TXT FRED.LST
  6508.     IF ERRORLEVEL 1 GOTO QUIT
  6509.     RENAME C:\POM\POMLOG.TXT FRED.LOG
  6510.     :QUIT
  6511.  
  6512.     The IF ERRORLEVEL lines jump to the end of the batch file if Parse-O-Matic
  6513.     generates an error of 1 or higher.  When coding batch files, remember that
  6514.     the IF ERRORLEVEL command is considered "True" if the error is the
  6515.     specified value or higher.  This means you should always test the higher
  6516.     value first.  See your DOS manual for details.
  6517.  
  6518.  
  6519.                                       --------
  6520.                                       Examples
  6521.                                       --------
  6522.  
  6523.     Many of the techniques described in this manual are demonstrated by the
  6524.     examples provided with the standard Parse-O-Matic package.  To see these
  6525.     examples, switch to your Parse-O-Matic directory, type START at the DOS
  6526.     prompt, or run START.BAT from Windows or OS/2, then select TUTORIAL.
  6527.  
  6528.  
  6529.     ===========================================================================
  6530.                                RUNNING UNDER WINDOWS
  6531.     ===========================================================================
  6532.  
  6533.  
  6534.                                    -------------
  6535.                                    Compatibility
  6536.                                    -------------
  6537.  
  6538.     Parse-O-Matic is a DOS program, which has a few advantages and a few minor
  6539.     disadvantages for Windows users.
  6540.  
  6541.     The primary advantage is that a Parse-O-Matic application can run on any
  6542.     PC-compatible machine, whether it is running DOS, Windows, or OS/2.
  6543.     Emulators are also available which will let you run Parse-O-Matic (and
  6544.     other DOS software) on Macintosh computers.
  6545.  
  6546.     Since Parse-O-Matic has no user interface to speak of, Windows' wonderful
  6547.     graphical environment is not particularly important.  The only operational
  6548.     difference is that to interrupt Parse-O-Matic processing, you press the Esc
  6549.     key instead of clicking on a Cancel button.
  6550.  
  6551.     Performance is a consideration if you are running Parse-O-Matic at the same
  6552.     time as 32-bit applications under Windows 95 or NT; it will slow them down
  6553.     slightly.  However, unless you are multi-tasking heavily, performance is
  6554.     not an issue because the usual bottleneck is the responsiveness and
  6555.     transfer speed of the hard disk, not the speed at which the Parse-O-Matic
  6556.     program runs.
  6557.  
  6558.  
  6559.                              -------------------------
  6560.                              Setting Up for Windows 95
  6561.                              -------------------------
  6562.  
  6563.     To use Parse-O-Matic under Windows 95, you need the following items, which
  6564.     are included in the standard Parse-O-Matic package:
  6565.  
  6566.     1)  The POM file (icon file POM_FILE.ICO)
  6567.     2)  A batch file (icon file BAT.ICO)
  6568.  
  6569.     These two icon files are included in the standard Parse-O-Matic package.
  6570.     You may find it helpful to copy them to your main Windows directory so
  6571.     that the the associations you set for them are not lost if you install
  6572.     a new version of Parse-O-Matic and then delete the original POM directory.
  6573.  
  6574.  
  6575.     Setting Up an Association for the POM File
  6576.     ------------------------------------------
  6577.  
  6578.     When you click on a POM file, it should call up a text editor.  To configure
  6579.     this, follow these steps:
  6580.  
  6581.     1)  Double-click on "My Computer"
  6582.  
  6583.     2)  From the pull-down menu, select View/Options
  6584.  
  6585.     3)  Dialog Box:  Options
  6586.         Click on the File Types tab
  6587.         Click on the New Type button
  6588.  
  6589.     4)  Dialog Box:  Add New File Type
  6590.         Description:  Parse-O-Matic Control File
  6591.         Associated extension:  POM
  6592.         Click on the New button
  6593.  
  6594.     5)  Dialog Box:  New Action
  6595.         Action:  &Edit
  6596.         Application used:  NOTEPAD.EXE (or the path to your favourite editor)
  6597.         Click on the OK button
  6598.  
  6599.     6)  Dialog Box:  Add New File Type
  6600.         Click on the Change Icon button
  6601.         Click on the Browse button
  6602.         File name: The full path to POM_FILE.ICO (e.g. C:\POM\POM_FILE.ICO)
  6603.         Press Enter
  6604.  
  6605.     7)  Dialog Box:  Change Icon
  6606.         Click the OK button
  6607.  
  6608.     8)  Dialog Box:  Add New File Type
  6609.         Click the Close button
  6610.  
  6611.     9)  Dialog Box: Options
  6612.         Click the Close button
  6613.  
  6614.     Once you have followed these steps, you can double-click on the POM file
  6615.     icon when you are in Windows Explorer or a file folder, and it will be
  6616.     opened with the file editor you specified in step 5.
  6617.  
  6618.  
  6619.     Setting Up an Association for the BAT File (Optional)
  6620.     -----------------------------------------------------
  6621.  
  6622.     Windows 95 is already set up to process batch (BAT) files.  However,
  6623.     Parse-O-Matic comes with an alternative icon which is more distinctive than
  6624.     the one supplied with Windows.  (The Parse-O-Matic icon looks like a bat --
  6625.     a sonar-equipped flying critter with the undeserved bad reputation).
  6626.  
  6627.     To change the icon, follow these steps:
  6628.  
  6629.     1)  Double-click on "My Computer"
  6630.  
  6631.     2)  From the pull-down menu, select View/Options
  6632.  
  6633.     3)  Dialog Box:  Options
  6634.         On the list box, find and double-click on MS-DOS Batch File
  6635.  
  6636.     4)  Dialog Box:  Edit File Type
  6637.         Click on the Change Icon button
  6638.  
  6639.     5)  Dialog Box:  Change Icon
  6640.         Click the Browse button
  6641.         File name: The full path to BAT.ICO (e.g. C:\POM\BAT.ICO)
  6642.         Press Enter
  6643.  
  6644.     6)  Dialog Box:  Change Icon
  6645.         Click the OK button
  6646.  
  6647.     7)  Dialog Box:  Edit File Type
  6648.         Click the Close button
  6649.  
  6650.     8)  Dialog Box: Options
  6651.         Click the Close button
  6652.  
  6653.     After following this procedure, your batch (BAT) file icons will be much
  6654.     more noticeable when they appear in Windows Explorer or a file folder.  To
  6655.     edit the batch file, right-click on the icon and select Edit.  To run the
  6656.     batch file, simply double-click the icon.
  6657.  
  6658.     For a discussion of batch files, see "Effective Use of Batch Files".
  6659.  
  6660.  
  6661.                            ------------------------------
  6662.                            Installing the ShowNum Utility
  6663.                            ------------------------------
  6664.  
  6665.     The ShowNum program is a small utility which converts a hex number to
  6666.     decimal and vice-versa (see "The ShowNum Utility").
  6667.  
  6668.     To install ShowNum as a Windows 95 shortcut:
  6669.  
  6670.     1)  Select "File/New/Shortcut" from the pull-down menu of any folder.
  6671.  
  6672.     2)  Specify the path name to SHOWNUM.BAT, followed by a question mark.
  6673.         For example:  C:\POM\SHOWNUM.BAT ?
  6674.         The ? means "prompt for input before calling the batch file".
  6675.  
  6676.     3)  After you have finished defining the shortcut, right-click on the icon,
  6677.         select "Properties", then the "Program" tab, and make sure the "Close
  6678.         on exit" box is checked off.
  6679.  
  6680.     You can then use ShowNum by double-clicking its icon.  You will be prompted
  6681.     to enter a number, and the answer will be displayed.
  6682.  
  6683.  
  6684.                               ------------------------
  6685.                               Long File Names in Win95
  6686.                               ------------------------
  6687.  
  6688.     Although Parse-O-Matic can be run under Windows 95, it will only recognize
  6689.     standard DOS file names; it does not use the long file names supported by
  6690.     Win95. You can determine the underlying DOS name of a file by checking its
  6691.     "Properties" in Windows Explorer, or by using the DIR command while in DOS
  6692.     mode.
  6693.  
  6694.  
  6695.  
  6696.     ===========================================================================
  6697.                                      LICENSING
  6698.     ===========================================================================
  6699.  
  6700.  
  6701.     This product is available in several forms.  For billing and pricing
  6702.     information, view or print the files OPTIONS.DOC and ORDER.FRM.
  6703.  
  6704.     TRIAL COPY:  If you have a "test-drive" evaluation copy, you will see a
  6705.     "Registration Reminder Screen" when you start up the program.  You are
  6706.     entitled to evaluate this program at no cost for 3 months.  If you continue
  6707.     to use it after that, you must register your copy and purchase a license,
  6708.     as described below.
  6709.  
  6710.     SINGLE-USER LICENSE:  When you register an evaluation copy of this product,
  6711.     you will receive the latest version, plus an unlocking code that will let
  6712.     you register any new evaluation versions that we release for a period of
  6713.     two years (six years for deluxe registration).
  6714.  
  6715.     SITE/MULTI-COPY LICENSES:  If you plan to run 15 or more copies of this
  6716.     program (on a network or on separate computers), you can obtain quantity
  6717.     pricing.  For details, view or print the text file ORDER.FRM.
  6718.  
  6719.     LAN LICENSE:  Local Area Network users must purchase a license for each
  6720.     user (see "Single-User License" and "Site/Multi-Copy Licenses"), although
  6721.     they can reduce this amount if they have run-control software which sets an
  6722.     upper limit on the number of concurrent users for a given program.
  6723.  
  6724.     WAN LICENSE:  Wide Area Networks are treated like LANs, but you may find it
  6725.     more economical to purchase a Distribution License (see below).
  6726.  
  6727.     DISTRIBUTION LICENSE:  The distribution license allows you to use an
  6728.     unlimited number of copies.  You may include it in your application or
  6729.     commercial package as a utility.  The only restriction is that you may not
  6730.     distribute this document (i.e. the user manual) or its essential content.
  6731.     With this safeguard, we avoid placing ourselves in competition with you;
  6732.     the program must be used to support an application or product rather than
  6733.     being its main feature.
  6734.  
  6735.     SOURCE CODE LICENSE:  If you purchase the Turbo Pascal source code, you
  6736.     must also purchase a license for each machine that will run the modified
  6737.     program.  Those portions of the source code written by Pinnacle Software
  6738.     remain copyrighted by Pinnacle, and may not be divulged to another party.
  6739.     As an alternative to purchasing the source code, you can also contract for
  6740.     us to make custom modifications to the program.
  6741.  
  6742.     RETAIL LICENSE:  You can sell complete, registered copies of this product,
  6743.     complete with documentation, in return for royalties.  The terms depend on
  6744.     volume and advance payments. Contact us for details.
  6745.  
  6746.  
  6747.